diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index dde2dba1845..00000000000 --- a/.eslintignore +++ /dev/null @@ -1,9 +0,0 @@ -# TODO: Use eslint on js lib and generated code - -# Ignore lib/js for now, which uses jshint currently -lib/js/* -# Ignore all generated code for now -**/gen-* - -# Don't lint nested node_modules -**/node_modules diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index 0aae820ecdb..00000000000 --- a/.eslintrc.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "env": { - "es6": true, - "node": true - }, - "extends": [ - "eslint:recommended", - "plugin:prettier/recommended" - ], - "parserOptions": { - "ecmaVersion": 2017 - }, - "rules": { - "no-console": "off", - "no-var": "error", - "prefer-const": "error", - "no-constant-condition": [ - "error", - { - "checkLoops": false - } - ] - } -} diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8f72f892520..4c67d7fcd14 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -42,7 +42,9 @@ jobs: compiler: strategy: matrix: - os: [ubuntu-20.04, ubuntu-22.04] + os: + - ubuntu-22.04 + - ubuntu-24.04 fail-fast: false runs-on: ${{ matrix.os }} steps: @@ -68,23 +70,76 @@ jobs: - name: Run thrift version run: /usr/local/bin/thrift -version - # only upload while building ubuntu-20.04 + # only upload while building ubuntu-24.04 - name: Archive built thrift compiler - if: matrix.os == 'ubuntu-20.04' - uses: actions/upload-artifact@v3 + if: matrix.os == 'ubuntu-24.04' + uses: actions/upload-artifact@v4 with: name: thrift-compiler path: compiler/cpp/thrift retention-days: 3 + lib-php: + needs: compiler + runs-on: ubuntu-24.04 + strategy: + matrix: + php-version: [7.1, 7.2, 7.3, 7.4, 8.0, 8.1, 8.2, 8.3] + fail-fast: false + steps: + - uses: actions/checkout@v4 + + - name: Set up PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-version }} + extensions: mbstring, intl, xml, curl + ini-values: "error_reporting=E_ALL" + + - name: Install Dependencies + run: composer install + + - name: Run bootstrap + run: ./bootstrap.sh + + - name: Run configure + run: | + ./configure $(echo $CONFIG_ARGS_FOR_LIBS | sed 's/without-php/with-php/' | sed 's/without-php_extension/with-php_extension/' ) + + - uses: actions/download-artifact@v4 + with: + name: thrift-compiler + path: compiler/cpp + + - name: Run thrift-compiler + run: | + chmod a+x compiler/cpp/thrift + compiler/cpp/thrift -version + + - name: Build Thrift Classes + run: | + mkdir -p ./lib/php/test/Resources/packages/php + mkdir -p ./lib/php/test/Resources/packages/phpv + mkdir -p ./lib/php/test/Resources/packages/phpvo + mkdir -p ./lib/php/test/Resources/packages/phpjs + mkdir -p ./lib/php/test/Resources/packages/phpcm + compiler/cpp/thrift --gen php:nsglobal="Basic" -r --out ./lib/php/test/Resources/packages/php lib/php/test/Resources/ThriftTest.thrift + compiler/cpp/thrift --gen php:validate,nsglobal="Validate" -r --out ./lib/php/test/Resources/packages/phpv lib/php/test/Resources/ThriftTest.thrift + compiler/cpp/thrift --gen php:validate,oop,nsglobal="ValidateOop" -r --out ./lib/php/test/Resources/packages/phpvo lib/php/test/Resources/ThriftTest.thrift + compiler/cpp/thrift --gen php:json,nsglobal="Json" -r --out ./lib/php/test/Resources/packages/phpjs lib/php/test/Resources/ThriftTest.thrift + compiler/cpp/thrift --gen php:classmap,server,rest,nsglobal="Classmap" -r --out ./lib/php/test/Resources/packages/phpcm lib/php/test/Resources/ThriftTest.thrift + + - name: Run Tests + run: vendor/bin/phpunit -c lib/php/phpunit.xml + lib-go: needs: compiler - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 strategy: matrix: go: - - '1.21' - - '1.22' + - '1.23' + - '1.24' fail-fast: false steps: - uses: actions/checkout@v4 @@ -105,7 +160,7 @@ jobs: run: | ./configure $(echo $CONFIG_ARGS_FOR_LIBS | sed 's/without-go/with-go/') - - uses: actions/download-artifact@v3 + - uses: actions/download-artifact@v4 with: name: thrift-compiler path: compiler/cpp @@ -128,8 +183,8 @@ jobs: run: make -C test/go precross - name: Upload go precross artifacts - if: matrix.go == '1.22' - uses: actions/upload-artifact@v3 + if: matrix.go == '1.24' + uses: actions/upload-artifact@v4 with: name: go-precross if-no-files-found: error @@ -139,7 +194,7 @@ jobs: lib-java-kotlin: needs: compiler - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 env: GRADLE_VERSION: "8.4" steps: @@ -183,7 +238,7 @@ jobs: run: | ./configure $(echo $CONFIG_ARGS_FOR_LIBS | sed 's/without-java/with-java/' | sed 's/without-kotlin/with-kotlin/') - - uses: actions/download-artifact@v3 + - uses: actions/download-artifact@v4 with: name: thrift-compiler path: compiler/cpp @@ -201,7 +256,7 @@ jobs: run: make -C lib/java install - name: Upload java libthrift artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: libthrift if-no-files-found: error @@ -214,7 +269,7 @@ jobs: run: make -C lib/java precross - name: Upload java precross artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: java-precross if-no-files-found: error @@ -236,7 +291,7 @@ jobs: run: make -C lib/kotlin precross - name: Upload kotlin precross artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: kotlin-precross if-no-files-found: error @@ -245,9 +300,73 @@ jobs: lib/kotlin/cross-test-server/build/install/TestServer/ retention-days: 3 + lib-netstd: + needs: compiler + runs-on: ubuntu-24.04 + strategy: + fail-fast: false + steps: + - uses: actions/checkout@v4 + + - name: Install dependencies + run: | + sudo apt-get update -yq + sudo apt-get install -y --no-install-recommends $BUILD_DEPS + sudo apt-get install -y --no-install-recommends curl openssl ca-certificates + +# the sdk is installed by default, but keep this step for reference +# caveat: net9 is (currently?) NOT installed, so manually again + - name: Set up .NET SDK + run: | + sudo add-apt-repository -y ppa:dotnet/backports + sudo apt-get install -y --no-install-recommends dotnet-sdk-9.0 +# end + + - name: Run bootstrap + run: ./bootstrap.sh + + - name: Run configure for netstd + run: | + ./configure $(echo $CONFIG_ARGS_FOR_LIBS | sed 's/without-netstd/with-netstd/') + + - uses: actions/download-artifact@v4 + with: + name: thrift-compiler + path: compiler/cpp + + - name: Run thrift-compiler + run: | + chmod a+x compiler/cpp/thrift + compiler/cpp/thrift -version + + - name: Run make for netstd + run: make -C lib/netstd + + - name: Run make install for netstd + run: sudo make -C lib/netstd install + + - name: Run make check for netstd + run: make -C lib/netstd check + + - name: Run make check for test/netstd + run: make -C test/netstd check + + - name: Run make precross for test/netstd + run: make -C test/netstd precross + + - name: Upload netstd precross artifacts + uses: actions/upload-artifact@v4 + with: + name: netstd-precross + if-no-files-found: error + path: | + test/netstd/Client/bin/Release/ + test/netstd/Server/bin/Release/ + retention-days: 3 + lib-swift: needs: compiler - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 @@ -258,7 +377,7 @@ jobs: run: | ./configure $(echo $CONFIG_ARGS_FOR_LIBS | sed 's/without-swift/with-swift/') - - uses: actions/download-artifact@v3 + - uses: actions/download-artifact@v4 with: name: thrift-compiler path: compiler/cpp @@ -272,7 +391,7 @@ jobs: run: make -C test/swift precross - name: Upload swift precross artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: swift-precross if-no-files-found: error @@ -283,9 +402,9 @@ jobs: lib-rust: needs: compiler - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 env: - TOOLCHAIN_VERSION: 1.65.0 + TOOLCHAIN_VERSION: 1.83.0 steps: - uses: actions/checkout@v4 @@ -311,7 +430,7 @@ jobs: run: | ./configure $(echo $CONFIG_ARGS_FOR_LIBS | sed 's/without-rs/with-rs/') - - uses: actions/download-artifact@v3 + - uses: actions/download-artifact@v4 with: name: thrift-compiler path: compiler/cpp @@ -334,7 +453,7 @@ jobs: run: make -C test/rs precross - name: Upload rust precross artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: rs-precross if-no-files-found: error @@ -348,7 +467,7 @@ jobs: lib-python: needs: compiler - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 strategy: matrix: python-version: @@ -382,7 +501,7 @@ jobs: run: | ./configure $(echo $CONFIG_ARGS_FOR_LIBS | sed 's/without-py3/with-py3/') - - uses: actions/download-artifact@v3 + - uses: actions/download-artifact@v4 with: name: thrift-compiler path: compiler/cpp @@ -404,6 +523,35 @@ jobs: - name: Run make check for python run: make -C lib/py check + lib-nodejs: + needs: compiler + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@v4 + + - name: Run bootstrap + run: ./bootstrap.sh + + - name: Run configure + run: | + ./configure $(echo $CONFIG_ARGS_FOR_LIBS | sed -E 's/without-node([tj])s/with-node\1s/g') + + - uses: actions/download-artifact@v4 + with: + name: thrift-compiler + path: compiler/cpp + + - name: Run thrift-compiler + run: | + chmod a+x compiler/cpp/thrift + compiler/cpp/thrift -version + + - name: Run js tests + run: make -C lib/nodejs check + + - name: Run ts tests + run: make -C lib/nodets check + cross-test: needs: - lib-java-kotlin @@ -411,7 +559,7 @@ jobs: - lib-rust - lib-go - lib-python - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 strategy: matrix: server_lang: ['java', 'kotlin', 'go', 'rs', 'swift'] @@ -438,31 +586,31 @@ jobs: sudo apt-get install -y --no-install-recommends openssl ca-certificates - name: Download java precross artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: java-precross path: lib/java/build - name: Download kotlin precross artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: kotlin-precross path: lib/kotlin - name: Download swift precross artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: swift-precross path: test/swift/CrossTests/.build/x86_64-unknown-linux-gnu/debug - name: Download rust precross artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: rs-precross path: test/rs/bin - name: Download go precross artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: go-precross path: test/go/bin @@ -477,6 +625,9 @@ jobs: test/rs/bin/* \ test/go/bin/* + - name: Create tmp domain socket folder + run: mkdir /tmp/v0.16 + - name: Run cross test env: THRIFT_CROSSTEST_CONCURRENCY: 4 @@ -488,10 +639,10 @@ jobs: --client ${{ matrix.client_lang }} - name: Upload log files from failed cross test runs - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: failure() with: - name: cross-test-log + name: cross-test-log_${{ matrix.server_lang }}-${{ matrix.client_lang }} path: test/log/ retention-days: 3 diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index 71748e8fc4d..c4ff747b549 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -14,7 +14,7 @@ permissions: jobs: compiler: - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 diff --git a/lib/py/src/compat.py b/.github/workflows/release_rust.yml similarity index 53% rename from lib/py/src/compat.py rename to .github/workflows/release_rust.yml index 0e8271dc193..04d4e33fdbf 100644 --- a/lib/py/src/compat.py +++ b/.github/workflows/release_rust.yml @@ -17,30 +17,32 @@ # under the License. # -import sys - -if sys.version_info[0] == 2: - - from cStringIO import StringIO as BufferIO - - def binary_to_str(bin_val): - return bin_val - - def str_to_binary(str_val): - return str_val - - def byte_index(bytes_val, i): - return ord(bytes_val[i]) - -else: - - from io import BytesIO as BufferIO # noqa - - def binary_to_str(bin_val): - return bin_val.decode('utf8') - - def str_to_binary(str_val): - return bytes(str_val, 'utf8') - - def byte_index(bytes_val, i): - return bytes_val[i] +name: Release Rust Packages + +on: + push: + tags: + - "*" + pull_request: + branches: + - master + paths: + - ".github/workflows/release_rust.yml" + workflow_dispatch: + +jobs: + publish: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Dryrun + working-directory: lib/rs + run: cargo publish --dry-run + + - name: Publish + working-directory: lib/rs + # Only publish if it's a tag and the tag is not a pre-release + if: ${{ startsWith(github.ref, 'refs/tags/') && !contains(github.ref, '-') }} + run: cargo publish + env: + CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} diff --git a/.gitignore b/.gitignore index cb8029c9888..6a0495bdaa9 100644 --- a/.gitignore +++ b/.gitignore @@ -75,6 +75,8 @@ project.lock.json /compiler/cpp/src/thrift/plugin/gen.stamp /compiler/cpp/Debug /compiler/cpp/Release +/compiler/cpp/compiler/Debug +/compiler/cpp/compiler/Release /compiler/cpp/src/thrift/libparse.a /compiler/cpp/src/thrift/thriftl.cc /compiler/cpp/src/thrift/thrifty.cc @@ -209,7 +211,6 @@ project.lock.json /lib/delphi/**/*.local /lib/delphi/**/*.dcu /lib/delphi/**/*.2007 -/lib/delphi/**/codegen/*.bat /lib/erl/.eunit /lib/erl/.generated /lib/erl/.rebar/ @@ -279,9 +280,8 @@ project.lock.json /lib/php/src/ext/thrift_protocol/run-tests.php /lib/php/src/ext/thrift_protocol/thrift_protocol.la /lib/php/src/ext/thrift_protocol/tmp-php.ini -/lib/php/src/packages/ -/lib/php/test/TEST-*.xml -/lib/php/test/packages/ +/lib/php/tests/Resources/packages/ +/lib/php/test/test-log-junit.xml /lib/py/dist/ /lib/erl/logs/ /lib/go/pkg diff --git a/.travis.yml b/.travis.yml index b771d70a4a5..99dd2bc0e2d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -47,7 +47,7 @@ env: - SCRIPT="cmake.sh" - BUILD_ARG="" - BUILD_ENV="-e CC=gcc -e CXX=g++ -e THRIFT_CROSSTEST_CONCURRENCY=4" - - DISTRO=ubuntu-bionic + - DISTRO=ubuntu-focal - BUILD_LIBS="CPP C_GLIB JAVA PYTHON TESTING TUTORIALS" # only meaningful for CMake builds - TRAVIS_BUILD_STAGE=test # DOCKER_REPO (this works for all builds as a source for docker images - you can override for fork builds in your Travis settings) @@ -58,12 +58,6 @@ env: jobs: include: # ========================= stage: docker ========================= - - stage: docker - script: true - env: - - JOB="Docker Build ubuntu-bionic 18.04 LTS" - - DISTRO=ubuntu-bionic - - TRAVIS_BUILD_STAGE=docker - script: true env: - JOB="Docker Build ubuntu-focal 20.04 LTS" @@ -131,12 +125,6 @@ jobs: - DISTRO=ubuntu-focal - SCRIPT="autotools.sh" - - script: build/docker/run.sh - env: - - JOB="Autotools (Ubuntu Bionic)" - - DISTRO=ubuntu-bionic - - SCRIPT="autotools.sh" - # ------------------------- phase: cmake ------------------------ - script: build/docker/run.sh env: diff --git a/ApacheThrift.nuspec b/ApacheThrift.nuspec index cd9a29c6c90..5a20f6286f7 100644 --- a/ApacheThrift.nuspec +++ b/ApacheThrift.nuspec @@ -19,14 +19,14 @@ the "Thrift" project. 2. nuget setApiKey 3. nuget pack ApacheThrift.nuspec -Symbols -SymbolPackageFormat snupkg - 4. nuget push ApacheThrift.0.20.0.nupkg -Source https://api.nuget.org/v3/index.json + 4. nuget push ApacheThrift.0.22.0.nupkg -Source https://api.nuget.org/v3/index.json --> ApacheThrift - 0.20.0 - Apache Thrift 0.20.0 + 0.22.0 + Apache Thrift 0.22.0 Apache Thrift Developers Apache Software Foundation Apache-2.0 @@ -36,7 +36,7 @@ Contains runtime libraries from lib/netstd for netstandard2.0 framework development. - + Apache Thrift RPC diff --git a/CHANGES.md b/CHANGES.md index bc2fed4750e..14968af8d0a 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,6 +1,170 @@ - # Apache Thrift Changelog +## 0.22.0 + +### Build Process + +- [THRIFT-5836](https://issues.apache.org/jira/browse/THRIFT-5836) - 0.21.0 fails to build from sources at Arch Linux: No rule to make target 'Thrift5272.thrift', needed by 'gen-cpp/Thrift5272_types.h' +- [THRIFT-5860](https://issues.apache.org/jira/browse/THRIFT-5860) - cmake 3.5 as a minimum version does not work with cmake 4.0.0 + +### C glib + +- [THRIFT-5817](https://issues.apache.org/jira/browse/THRIFT-5817) - [C++] Avoid copy of TUuid + +### C++ + +- [THRIFT-5637](https://issues.apache.org/jira/browse/THRIFT-5637) - Thrift compiler should be able to output c++ Aggregate types +- [THRIFT-5667](https://issues.apache.org/jira/browse/THRIFT-5667) - Make ThriftConfig.cmake relocatable +- [THRIFT-5817](https://issues.apache.org/jira/browse/THRIFT-5817) - [C++] Avoid copy of TUuid +- [THRIFT-5821](https://issues.apache.org/jira/browse/THRIFT-5821) - Cannot compile against aws-lc libcrypto (openssl replacement from AWS) +- [THRIFT-5841](https://issues.apache.org/jira/browse/THRIFT-5841) - possible init/deinit conflict with manual initialization flag +- [THRIFT-5853](https://issues.apache.org/jira/browse/THRIFT-5853) - Remove oldstyle casts from TBufferTransports and TCompactProtocol +- [THRIFT-5854](https://issues.apache.org/jira/browse/THRIFT-5854) - TCompactProtocol readString checks maxMessageSize at wrong position and off by one +- [THRIFT-5868](https://issues.apache.org/jira/browse/THRIFT-5868) - UUID Support for TCompactProtocol +- [THRIFT-5865](https://issues.apache.org/jira/browse/THRIFT-5865) - Fix TBinayProtocol with list + + +### Compiler (General) + +- [THRIFT-5823](https://issues.apache.org/jira/browse/THRIFT-5823) - Fix illegal uses of exceptions as normal struct type +- [THRIFT-5835](https://issues.apache.org/jira/browse/THRIFT-5835) - Allow exceptions to be used as regular struct datatype + +# Delphi + +- [THRIFT-5822](https://issues.apache.org/jira/browse/THRIFT-5822) - Remove deprecated AnsiString functions from the library +- [THRIFT-5824](https://issues.apache.org/jira/browse/THRIFT-5824) - Migrate, refactor and improve Delphi code generation test script +- [THRIFT-5825](https://issues.apache.org/jira/browse/THRIFT-5825) - UUID constants lead to uncompileable Delphi code +- [THRIFT-5826](https://issues.apache.org/jira/browse/THRIFT-5826) - binary constants create uncompilable Delphi code +- [THRIFT-5827](https://issues.apache.org/jira/browse/THRIFT-5827) - enums in typedefs are not resolved in all cases +- [THRIFT-5837](https://issues.apache.org/jira/browse/THRIFT-5837) - Delphi implementation for THRIFT-5835 +- [THRIFT-5839](https://issues.apache.org/jira/browse/THRIFT-5839) - incorrect cast under Win64 +- [THRIFT-5850](https://issues.apache.org/jira/browse/THRIFT-5850) - Switch IThriftConfiguration interface from Cardinal to Integer +- [THRIFT-5851](https://issues.apache.org/jira/browse/THRIFT-5851) - Promote known total stream sizes for seekable stream transports properly +- [THRIFT-5856](https://issues.apache.org/jira/browse/THRIFT-5856) - Client should validate HTTP status + +### Go + +- [THRIFT-5833](https://issues.apache.org/jira/browse/THRIFT-5833) - go: Combine I/O and original error in compiler generated Process functions +- [THRIFT-5845](https://issues.apache.org/jira/browse/THRIFT-5845) - The write error for union fields should be TException +- [THRIFT-5859](https://issues.apache.org/jira/browse/THRIFT-5859) - go: Generate a map for know values of an enum type + +### Java + +- [THRIFT-5858](https://issues.apache.org/jira/browse/THRIFT-5858) - Introduce new type MESSAGE_SIZE_LIMIT in TTransportException + +### netstd + +- [THRIFT-5832](https://issues.apache.org/jira/browse/THRIFT-5832) - Drop net6 support and add net9 instead +- [THRIFT-5838](https://issues.apache.org/jira/browse/THRIFT-5838) - THttpTransport.FlushAsync does not include original exception +- [THRIFT-5852](https://issues.apache.org/jira/browse/THRIFT-5852) - Promote known total stream sizes for seekable stream transports + +### Node.js + +- [THRIFT-5811](https://issues.apache.org/jira/browse/THRIFT-5811) - Add ES module support to JS codegen +- [THRIFT-5848](https://issues.apache.org/jira/browse/THRIFT-5848) - Expose InputBufferUnderrunError in nodejs client +- [THRIFT-5849](https://issues.apache.org/jira/browse/THRIFT-5849) - Expose createClient in browser version of nodejs package + +### PHP + +- [THRIFT-1482](https://issues.apache.org/jira/browse/THRIFT-1482) - Unix domain socket support under PHP +- [THRIFT-5829](https://issues.apache.org/jira/browse/THRIFT-5829) - PHP lib Use of "static" in callables is deprecated notice + +### Python + +- [THRIFT-5024](https://issues.apache.org/jira/browse/THRIFT-5024) - tutorial\py.tornado\PythonServer.py failed under Tornado6 +- [THRIFT-5847](https://issues.apache.org/jira/browse/THRIFT-5847) - Python3.12 deprecation in THttpClient +- [THRIFT-5857](https://issues.apache.org/jira/browse/THRIFT-5857) - Remove deprecated Tornado io_loop usage +- [THRIFT-5861](https://issues.apache.org/jira/browse/THRIFT-5861) - Add isOpen method to TTornadoStreamTransport + +### Swift + +- [THRIFT-4838](https://issues.apache.org/jira/browse/THRIFT-4838) - add unix domain socket support to Swift TSocketTransport implementation + + +## 0.21.0 + +### Build Process + +- [THRIFT-5815](https://issues.apache.org/jira/browse/THRIFT-5815) - veralign.sh broken and incomplete +- [THRIFT-5810](https://issues.apache.org/jira/browse/THRIFT-5810) - Wrong installation path for static MSVC libs. +- [THRIFT-5755](https://issues.apache.org/jira/browse/THRIFT-5755) - Docker image build fail + +### C++ + +- [THRIFT-5272](https://issues.apache.org/jira/browse/THRIFT-5272) - printTo does not properly handle i8 datatypes +- [THRIFT-5492](https://issues.apache.org/jira/browse/THRIFT-5492) - Bogus END_OF_FILE exception +- [THRIFT-5678](https://issues.apache.org/jira/browse/THRIFT-5678) - TConnectedClient: warning due to non-virtual dtor +- [THRIFT-5682](https://issues.apache.org/jira/browse/THRIFT-5682) - UB in generated C++ code stops compiling with C++20" +- [THRIFT-5709](https://issues.apache.org/jira/browse/THRIFT-5709) - Drastically improve `to_num()` performace +- [THRIFT-5772](https://issues.apache.org/jira/browse/THRIFT-5772) - Add UUID support for C++ +- [THRIFT-5773](https://issues.apache.org/jira/browse/THRIFT-5773) - UUID wrapper for C++ +- [THRIFT-5816](https://issues.apache.org/jira/browse/THRIFT-5816) - Fix UUID for boost 1.86.0 (change in data member usage) + +### Compiler (General) + +- [THRIFT-5800](https://issues.apache.org/jira/browse/THRIFT-5800) - "Could not find include file foo.thrift" probably should be failure instead of warning +- [THRIFT-5766](https://issues.apache.org/jira/browse/THRIFT-5766) - Replace std::endl with "\n" + +### Delphi + +- [THRIFT-5789](https://issues.apache.org/jira/browse/THRIFT-5789) - Refactor test suite client implementation +- [THRIFT-5782](https://issues.apache.org/jira/browse/THRIFT-5782) - implement full deprecation support +- [THRIFT-5750](https://issues.apache.org/jira/browse/THRIFT-5750) - Remove "ansistr_binary_" option +- [THRIFT-5788](https://issues.apache.org/jira/browse/THRIFT-5788) - Refactor and streamline hash set implementation +- [THRIFT-5765](https://issues.apache.org/jira/browse/THRIFT-5765) - Extra override for WriteBinary() to avoid unnecessary memory allocations when using COM types +- [THRIFT-5764](https://issues.apache.org/jira/browse/THRIFT-5764) - Extra CTOR for TThriftBytesImpl + +### Go + +- [THRIFT-5786](https://issues.apache.org/jira/browse/THRIFT-5786) - Full deprecation support for go +- [THRIFT-5654](https://issues.apache.org/jira/browse/THRIFT-5654) - LNK4042 and LNK2019 in go_validator_generator.cc +- [THRIFT-5784](https://issues.apache.org/jira/browse/THRIFT-5784) - go: Add THeaderTransforms to TConfiguration + +### Java + +- [THRIFT-5762](https://issues.apache.org/jira/browse/THRIFT-5762) - Expose service result objects in Java +- [THRIFT-5530](https://issues.apache.org/jira/browse/THRIFT-5530) - could not resolve plugin artifact 'com.github.johnrengelman.shadow:com.github.johnrengelman.shadow.gradle.plugin:4.0.4' +- [THRIFT-5230](https://issues.apache.org/jira/browse/THRIFT-5230) - Fix connection leak and CancelledKeyException when handling Epoll bug +- [THRIFT-4847](https://issues.apache.org/jira/browse/THRIFT-4847) - CancelledKeyException causes TThreadedSelectorServer to fail. + +### JSON + +- [THRIFT-5761](https://issues.apache.org/jira/browse/THRIFT-5761) - Lib/json tests fail + +### netstd + +- [THRIFT-5798](https://issues.apache.org/jira/browse/THRIFT-5798) - Expand netstd compile tests to fully cover all current target environments +- [THRIFT-5797](https://issues.apache.org/jira/browse/THRIFT-5797) - HashSet() CTOR takes no argument for net < 5 +- [THRIFT-5796](https://issues.apache.org/jira/browse/THRIFT-5796) - Indicate target environment via #if check +- [THRIFT-5795](https://issues.apache.org/jira/browse/THRIFT-5795) - namespace not properly escaped +- [THRIFT-5794](https://issues.apache.org/jira/browse/THRIFT-5794) - Uncompilable C# code in 0.20.0 +- [THRIFT-5781](https://issues.apache.org/jira/browse/THRIFT-5781) - implement full deprecation support +- [THRIFT-5780](https://issues.apache.org/jira/browse/THRIFT-5780) - Prevent certain warnings related to net8 +- [THRIFT-5787](https://issues.apache.org/jira/browse/THRIFT-5787) - .NET ApacheThrift client v20.0 breaks compatibility in TBinaryProtocol.Factory constructor +- [THRIFT-5783](https://issues.apache.org/jira/browse/THRIFT-5783) - drop net7 support + +### Node.js + +- [THRIFT-5769](https://issues.apache.org/jira/browse/THRIFT-5769) - Large messages crash Node.js client when using TFramedTransport + +### PHP + +- [THRIFT-5760](https://issues.apache.org/jira/browse/THRIFT-5760) - Update minimal version of php +- [THRIFT-5758](https://issues.apache.org/jira/browse/THRIFT-5758) - PHP 8.2 Deprecate dynamic properties +- [THRIFT-5756](https://issues.apache.org/jira/browse/THRIFT-5756) - Run php tests in github actions + +### Python + +- [THRIFT-4181](https://issues.apache.org/jira/browse/THRIFT-4181) - PEP 484 Type Hinting on generated code +- [THRIFT-5813](https://issues.apache.org/jira/browse/THRIFT-5813) - Clarify TSocket state after isOpen +- [THRIFT-5777](https://issues.apache.org/jira/browse/THRIFT-5777) - timeout exception mismatched +- [THRIFT-5139](https://issues.apache.org/jira/browse/THRIFT-5139) - Type hinting for Python library + +### Rust + +- [THRIFT-5812](https://issues.apache.org/jira/browse/THRIFT-5812) - Capacity overflow in Rust server + + ## 0.20.0 ### Known Open Issues (Blocker or Critical) diff --git a/CMakeLists.txt b/CMakeLists.txt index a685e4f3705..1f74e75c5f8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,7 +17,7 @@ # under the License. # -cmake_minimum_required(VERSION 3.4) +cmake_minimum_required(VERSION 3.16) if(POLICY CMP0048) cmake_policy(SET CMP0048 NEW) # package version behavior added in cmake 3.0 @@ -28,7 +28,7 @@ endif() # PACKAGE_VERSION is used by cpack scripts currently # Both thrift_VERSION and PACKAGE_VERSION should be the same for now -set(thrift_VERSION "0.20.0") +set(thrift_VERSION "0.22.0") set(PACKAGE_VERSION ${thrift_VERSION}) project("thrift" VERSION ${PACKAGE_VERSION}) diff --git a/LANGUAGES.md b/LANGUAGES.md index 4952ade158b..27877ba8d3d 100644 --- a/LANGUAGES.md +++ b/LANGUAGES.md @@ -1,6 +1,11 @@ # Apache Thrift Language Support # -Guidance For: 0.17.0 | +Guidance For: 0.22.0 | +[0.21.0](https://github.com/apache/thrift/blob/v0.21.0/LANGUAGES.md) | +[0.20.0](https://github.com/apache/thrift/blob/v0.20.0/LANGUAGES.md) | +[0.19.0](https://github.com/apache/thrift/blob/v0.19.0/LANGUAGES.md) | +[0.18.0](https://github.com/apache/thrift/blob/v0.18.0/LANGUAGES.md) | +[0.17.0](https://github.com/apache/thrift/blob/v0.17.0/LANGUAGES.md) | [0.16.0](https://github.com/apache/thrift/blob/v0.16.0/LANGUAGES.md) | [0.15.0](https://github.com/apache/thrift/blob/v0.15.0/LANGUAGES.md) | [0.14.0](https://github.com/apache/thrift/blob/v0.14.0/LANGUAGES.md) | @@ -80,7 +85,7 @@ Thrift's core protocol is TBinary, supported by all languages except for JavaScr 0.2.0 YesYes C++11 - +Yes YesYesYesYesYesYes YesYesYesYes YesYesYesYes @@ -127,25 +132,25 @@ Thrift's core protocol is TBinary, supported by all languages except for JavaScr Delphi 0.8.0 -2010Alexandria 11.2 +2010Athens 12.2 Yes -Yes +YesYesYesYes YesYes YesYesYesYes Yes Delphi -.NET Standard +.NET 0.13.0 Yes -.NET Standard 2.x, .NET 6 +.NET Standard 2.x, net8, net9 Yes YesYesYesYes YesYes YesYesYesYes Yes -.NET Standard +.NET Erlang @@ -163,9 +168,9 @@ Thrift's core protocol is TBinary, supported by all languages except for JavaScr Go 0.7.0 Yes -1.211.22 - -YesYesYes +1.231.24 +Yes +YesYesYesYes YesYesYesYes YesYesYesYes Yes @@ -176,7 +181,7 @@ Thrift's core protocol is TBinary, supported by all languages except for JavaScr 0.9.3 Yes 4.1.54.2.5 - +Yes YesYes YesYes YesYesYesYes @@ -247,7 +252,7 @@ Thrift's core protocol is TBinary, supported by all languages except for JavaScr node.ts 0.12.0 Yes -3.1.6 +5.7.2 YesYes @@ -319,7 +324,7 @@ Thrift's core protocol is TBinary, supported by all languages except for JavaScr Rust 0.11.0 Yes -1.65.01.xx.x +1.83.01.xx.x YesYes Yes @@ -344,8 +349,8 @@ Thrift's core protocol is TBinary, supported by all languages except for JavaScr 0.12.0 Yes 5.7 - -YesYesYesYes +Yes +YesYesYesYesYes YesYes YesYesYes Yes @@ -359,7 +364,7 @@ Thrift's core protocol is TBinary, supported by all languages except for JavaScr autoconfcmake MinMax Uuid -Domain File Memory Pipe Socket TLS  +Domain File Memory Pipe Socket TLS  FramedHeader http  zlib  BinaryCompact JSON Multiplex ForkingNonblockingSimpleThreadedThreadPool diff --git a/Makefile.am b/Makefile.am index 5b9e9709f2f..735cd405929 100644 --- a/Makefile.am +++ b/Makefile.am @@ -131,13 +131,14 @@ skipped_files = $(subst $(space),$(comma),$(codespell_skip_files)) style-local: codespell --write-changes --skip=$(skipped_files) --disable-colors +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ .asf.yaml \ .clang-format \ .dockerignore \ .editorconfig \ - .eslintignore \ - .eslintrc.json \ .flake8 \ .gitattributes \ .gitignore \ @@ -147,6 +148,7 @@ EXTRA_DIST = \ .github/workflows/build.yml \ .github/workflows/cmake.yml \ .github/workflows/pypi.yml \ + .github/workflows/release_rust.yml \ .travis.yml \ ApacheThrift.nuspec \ appveyor.yml \ @@ -162,6 +164,7 @@ EXTRA_DIST = \ doap.rdf \ doc \ dub.json \ + eslint.config.mjs \ go.mod \ jitpack.yml \ LANGUAGES.md \ @@ -169,6 +172,7 @@ EXTRA_DIST = \ NOTICE \ package.json \ package-lock.json \ + Package.swift \ phpcs.xml.dist \ README.md \ rust-toolchain \ diff --git a/Package.swift b/Package.swift new file mode 100644 index 00000000000..773ea0569cc --- /dev/null +++ b/Package.swift @@ -0,0 +1,32 @@ +// swift-tools-version:5.1 +/* + * 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 PackageDescription + +let package = Package( + name: "Thrift", + products: [ + .library(name: "Thrift", targets: ["Thrift"]) + ], + targets: [ + .target(name: "Thrift", path: "lib/swift/Sources"), + .testTarget(name: "ThriftTests", dependencies: ["Thrift"], path: "lib/swift/Tests/ThriftTests") + ] +) diff --git a/Thrift.podspec b/Thrift.podspec index 8bf70f64f18..08ed58c7e46 100644 --- a/Thrift.podspec +++ b/Thrift.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'Thrift' - s.version = '0.20.0' + s.version = '0.22.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 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. @@ -10,6 +10,6 @@ The Apache Thrift scalable cross-language software framework for networked servi s.author = { 'Apache Thrift Developers' => 'dev@thrift.apache.org' } s.ios.deployment_target = '9.0' s.osx.deployment_target = '10.10' - s.source = { :git => 'https://github.com/apache/thrift.git', :tag => 'v0.20.0' } + s.source = { :git => 'https://github.com/apache/thrift.git', :tag => 'v0.22.0' } s.source_files = 'lib/swift/Sources/*.swift' end diff --git a/aclocal/ax_boost_base.m4 b/aclocal/ax_boost_base.m4 index d5403957637..4065af0d760 100644 --- a/aclocal/ax_boost_base.m4 +++ b/aclocal/ax_boost_base.m4 @@ -113,7 +113,7 @@ AC_DEFUN([_AX_BOOST_BASE_RUNDETECT],[ dnl are found, e.g. when only header-only libraries are installed! AS_CASE([${host_cpu}], [x86_64],[libsubdirs="lib64 libx32 lib lib64"], - [ppc64|powerpc64|s390x|sparc64|aarch64|ppc64le|powerpc64le|riscv64],[libsubdirs="lib64 lib lib64"], + [ppc64|powerpc64|s390x|sparc64|aarch64|ppc64le|powerpc64le|riscv64|loongarch64],[libsubdirs="lib64 lib lib64"], [libsubdirs="lib"] ) diff --git a/appveyor.yml b/appveyor.yml index 5847ea926ba..8efc5222d05 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -19,7 +19,7 @@ # build Apache Thrift on AppVeyor - https://ci.appveyor.com -version: '0.20.0.{build}' +version: '0.22.0.{build}' shallow_clone: true diff --git a/bower.json b/bower.json index 84f3a989012..871ab420de5 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "thrift", - "version": "0.20.0", + "version": "0.22.0", "homepage": "https://github.com/apache/thrift.git", "authors": [ "Apache Thrift " diff --git a/build/appveyor/MSVC-appveyor-full.bat b/build/appveyor/MSVC-appveyor-full.bat index 49a3f94a0e5..dcdf8434963 100644 --- a/build/appveyor/MSVC-appveyor-full.bat +++ b/build/appveyor/MSVC-appveyor-full.bat @@ -131,13 +131,12 @@ call build-libevent.bat || EXIT /B pip.exe ^ install backports.ssl_match_hostname ^ ipaddress ^ - six ^ tornado ^ twisted || 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 +appveyor DownloadFile https://fpdownload.adobe.com/pub/flex/sdk/builds/flex4.6/flex_sdk_4.6.0.23201B.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/cmake/DefineInstallationPaths.cmake b/build/cmake/DefineInstallationPaths.cmake index 23962b442d0..0c3dd094ac7 100644 --- a/build/cmake/DefineInstallationPaths.cmake +++ b/build/cmake/DefineInstallationPaths.cmake @@ -20,7 +20,9 @@ # Define the default install paths set(BIN_INSTALL_DIR "bin" CACHE PATH "The binary install dir (default: bin)") -if(MSVC) +# For MSVC builds, install shared libs to bin/, while keeping the install +# dir for static libs as lib/. +if(MSVC AND BUILD_SHARED_LIBS) set(LIB_INSTALL_DIR "bin${LIB_SUFFIX}" CACHE PATH "The library install dir (default: bin${LIB_SUFFIX})") else() set(LIB_INSTALL_DIR "lib${LIB_SUFFIX}" CACHE PATH "The library install dir (default: lib${LIB_SUFFIX})") diff --git a/build/cmake/DefineOptions.cmake b/build/cmake/DefineOptions.cmake index b59292cd3b9..b938d7c3542 100644 --- a/build/cmake/DefineOptions.cmake +++ b/build/cmake/DefineOptions.cmake @@ -87,7 +87,7 @@ CMAKE_DEPENDENT_OPTION(BUILD_C_GLIB "Build C (GLib) library" ON # OpenSSL if(WITH_CPP OR WITH_C_GLIB) - find_package(OpenSSL QUIET) + find_package(OpenSSL) CMAKE_DEPENDENT_OPTION(WITH_OPENSSL "Build with OpenSSL support" ON "OPENSSL_FOUND" OFF) endif() diff --git a/build/cmake/GenerateConfigModule.cmake b/build/cmake/GenerateConfigModule.cmake index 597ffd8f72c..15c094296ff 100644 --- a/build/cmake/GenerateConfigModule.cmake +++ b/build/cmake/GenerateConfigModule.cmake @@ -18,19 +18,16 @@ # 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 +# In CYGWIN environment 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 + INCLUDE_INSTALL_DIR + CMAKE_INSTALL_DIR + BIN_INSTALL_DIR ) write_basic_package_version_file("${CMAKE_CURRENT_BINARY_DIR}/ThriftConfigVersion.cmake" diff --git a/build/cmake/ThriftConfig.cmake.in b/build/cmake/ThriftConfig.cmake.in index 2f2003bb438..f52480104ce 100644 --- a/build/cmake/ThriftConfig.cmake.in +++ b/build/cmake/ThriftConfig.cmake.in @@ -21,11 +21,15 @@ 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 DEFINED THRIFT_COMPILER) - set(THRIFT_COMPILER "${THRIFT_BIN_DIR}/thrift@CMAKE_EXECUTABLE_SUFFIX@") +set_and_check(THRIFT_CMAKE_DIR "${CMAKE_CURRENT_LIST_DIR}") + +set_and_check(THRIFT_INCLUDE_DIR "@PACKAGE_INCLUDE_INSTALL_DIR@/thrift") + +if(@BUILD_COMPILER@) + set_and_check(THRIFT_BIN_DIR "@PACKAGE_BIN_INSTALL_DIR@") + if(NOT DEFINED THRIFT_COMPILER) + set(THRIFT_COMPILER "${THRIFT_BIN_DIR}/thrift@CMAKE_EXECUTABLE_SUFFIX@") + endif() endif() if (NOT TARGET thrift::thrift) @@ -40,6 +44,13 @@ if(@ZLIB_FOUND@ AND @WITH_ZLIB@) set(THRIFT_LIBRARIES thriftz::thriftz) endif() +if(@Qt5_FOUND@ AND @WITH_QT5@) + if (NOT TARGET thriftqt5::thriftqt5) + include("${THRIFT_CMAKE_DIR}/thriftqt5Targets.cmake") + endif() + set(THRIFT_LIBRARIES thriftqt5::thriftqt5) +endif() + if ("${THRIFT_LIBRARIES}" STREQUAL "") message(FATAL_ERROR "thrift libraries were not found") endif() diff --git a/build/docker/README.md b/build/docker/README.md index 9c9175ff824..1f67d1d7331 100644 --- a/build/docker/README.md +++ b/build/docker/README.md @@ -20,12 +20,12 @@ logic to determine their behavior: | Variable | Default | Usage | | -------- | ----- | ------- | -| `DISTRO` | `ubuntu-bionic` | Set by various build jobs in `.travis.yml` to run builds in different containers. Not intended to be set externally.| +| `DISTRO` | `ubuntu-focal` | Set by various build jobs in `.travis.yml` to run builds in different containers. Not intended to be set externally.| | `DOCKER_REPO` | `thrift/thrift-build` | The name of the Docker Hub repository to obtain and store docker images. | | `DOCKER_USER` | `` | The Docker Hub account name containing the repository. | | `DOCKER_PASS` | `` | The Docker Hub account password to use when pushing new tags. | -For example, the default docker image that is used in builds if no overrides are specified would be: `thrift/thrift-build:ubuntu-bionic` +For example, the default docker image that is used in builds if no overrides are specified would be: `thrift/thrift-build:ubuntu-focal` ### Forks ### @@ -46,14 +46,13 @@ Docker Hub and push the resulting tags. ## Supported Containers ## -The Travis CI (continuous integration) builds use the Ubuntu Bionic -(18.04 LTS) and Xenial (16.04 LTS) images to maximize language level +The Travis CI (continuous integration) builds use the Ubuntu Jammy +(22.04 LTS) and Focal (20.04 LTS) images to maximize language level coverage. ### Ubuntu ### * focal (stable, current) -* bionic (previous stable) * jammy (next stable, WIP) ## Unsupported Containers ## @@ -105,16 +104,16 @@ Then, to pull down the current image being used to build (the same way Travis CI does it) - if it is out of date in any way it will build a new one for you: - thrift$ DOCKER_REPO=thrift/thrift-build DISTRO=ubuntu-bionic build/docker/refresh.sh + thrift$ DOCKER_REPO=thrift/thrift-build DISTRO=ubuntu-focal build/docker/refresh.sh To run all unit tests (just like Travis CI does): - thrift$ dockerrun thrift/thrift-build:ubuntu-bionic + thrift$ dockerrun thrift/thrift-build:ubuntu-focal root@8caf56b0ce7b:/thrift/src# build/docker/scripts/autotools.sh To run the cross tests (just like Travis CI does): - thrift$ dockerrun thrift/thrift-build:ubuntu-bionic + thrift$ dockerrun thrift/thrift-build:ubuntu-focal root@8caf56b0ce7b:/thrift/src# build/docker/scripts/cross-test.sh When you are done, you want to clean up occasionally so that docker isn't using lots of extra disk space: @@ -136,7 +135,14 @@ If you do not want to use the same scripts Travis CI does, you can do it manuall Build the image: - thrift$ docker build -t thrift build/docker/ubuntu-bionic +Linux: + + thrift$ docker build --build-arg uid=$(id -u) --build-arg gid=$(id -g) -t thrift build/docker/ubuntu-jammy + +Windows/Mac: + + thrift$ docker build -t thrift build/docker/ubuntu-jammy + Open a command prompt in the image: @@ -144,53 +150,52 @@ Open a command prompt in the image: ## Core Tool Versions per Dockerfile ## -Last updated: October 1, 2017 +Last updated: March 5, 2024 -| Tool | ubuntu-xenial | ubuntu-bionic | Notes | +| Tool | ubuntu-focal | ubuntu-jammy | Notes | | :-------- | :------------ | :------------ | :---- | -| ant | 1.9.6 | 1.10.3 | | -| autoconf | 2.69 | 2.69 | | -| automake | 1.15 | 1.15.1 | | -| bison | 3.0.4 | 3.0.4 | | -| boost | 1.58.0 | 1.65.1 | | -| cmake | 3.5.1 | 3.10.2 | | -| cppcheck | 1.72 | 1.82 | | -| flex | 2.6.0 | 2.6.4 | | -| libc6 | 2.23 | 2.27 | glibc | -| libevent | 2.0.21 | 2.1.8 | | -| libstdc++ | 5.4.0 | 7.3.0 | | -| make | 4.1 | 4.1 | | -| openssl | 1.0.2g | 1.1.0g | | -| qt5 | 5.5.1 | 5.9.5 | | +| ant | 1.10.7 | 1.10.12 | | +| autoconf | 2.69 | 2.71 | | +| automake | 1.16.1 | 1.16.5 | | +| bison | 3.5.1 | 3.8.2 | | +| boost | 1.71.0 | 1.74.0 | | +| cmake | 3.16.3 | 3.22.1 | | +| cppcheck | 1.90 | 2.7 | | +| flex | 2.6.4 | 2.6.4 | | +| libc6 | 2.31 | 2.35 | glibc | +| libevent | 2.0.16 | 2.0.16 | | +| libstdc++ | 10.5.0 | 10.5.0 | | +| make | 4.2.1 | 4.3 | | +| openssl | 1.1.1f | 3.0.2 | | +| qt5 | 5.12.8 | 5.15.3 | | ## Compiler/Language Versions per Dockerfile ## -| Language | ubuntu-xenial | ubuntu-bionic | Notes | +| Language | ubuntu-focal | ubuntu-jammy | Notes | | :-------- | :------------ | :------------ | :---- | | as of | Mar 06, 2018 | Jul 1, 2019 | | -| as3 | | 4.6.0 | | -| C++ gcc | 5.4.0 | 7.4.0 | | -| C++ clang | 3.8 | 6.0 | | -| C# (mono) | 4.2.1.0 | 4.6.2.7 | | -| c\_glib | 2.48.2 | 2.56.4 | | +| as3 | 4.6.0 | 4.6.0 | | +| C++ gcc | 9.4.0 | 11.4.0 | | +| C++ clang | 13.0.0 | 13.0.0 | | +| c\_glib | 3.2.12 | 3.2.12 | | | cl (sbcl) | | 1.5.3 | | | d | 2.087.0 | 2.087.0 | | -| dart | 2.0.0 | 2.4.0 | | +| dart | 2.7.2-1 | 2.7.2-1 | | | delphi | | | Not in CI | -| erlang | OTP-20 | OTP-25 | | -| go | 1.15.10 | 1.16.2 | | -| haxe | 3.2.1 | 3.4.4 | THRIFT-4352: avoid 3.4.2 | -| java | 1.8.0\_191 | 17 | | -| js | Node.js 6.17.1, V8 5.1.281.111, npm 3.10.10 | Node.js 10.18.0, V8 6.8.275.32, npm 6.13.4 | | -| lua | | 5.2.4 | Lua 5.3: see THRIFT-4386 | -| netstd | 7.0 | 7.0 | | -| nodejs | 6.16.0 | 10.16.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.32 | 7.2.19 | | -| python | 2.7.12 | 2.7.15 | | -| python3 | 3.5.2 | 3.6.8 | | -| ruby | 2.3.1p112 | 2.5.1p57 | | -| rust | 1.65.0 | 1.65.0 | | +| erlang | OTP-25.3.2.9 | OTP-25.3.2.9 | | +| go | 1.21.7 | 1.21.7 | | +| haxe | 4.2.1 | 4.2.1 | | +| java | 17 | 17 | | +| js | Node.js 16.20.2, npm 8.19.4 | Node.js 16.20.2, npm 8.19.4 | | +| lua | 5.2.4 | 5.2.4 | Lua 5.3: see THRIFT-4386 | +| netstd | 9.0 | 9.0 | | +| nodejs | 16.20.2 | 16.20.2 | | +| ocaml | 4.08.1 | 4.13.1 | | +| perl | 5.30.0 | 5.34.0 | | +| php | 7.4.3 | 8.1.2 | | +| python2 | 2.7.18 | | | +| python3 | 3.8.10 | 3.10.12 | | +| ruby | 2.7.0p0 | 3.0.2p107 | | +| rust | 1.83.0 | 1.83.0 | | | smalltalk | | | Not in CI | -| swift | | 5.1.4 | | +| swift | 5.7 | 5.7 | | diff --git a/build/docker/msvc2017/Dockerfile b/build/docker/msvc2017/Dockerfile index d59c19568bc..a29753e0f78 100644 --- a/build/docker/msvc2017/Dockerfile +++ b/build/docker/msvc2017/Dockerfile @@ -67,7 +67,7 @@ RUN C:\BuildTools\Common7\Tools\VsDevCmd.bat -arch=amd64 && ` # Install zlib COPY appveyor\build-zlib.bat C:\TEMP\build-zlib.bat -ENV ZLIB_VERSION=1.2.11 +ENV ZLIB_VERSION=1.2.13 ENV WIN3P=C:\TEMP\WIN3P RUN C:\BuildTools\Common7\Tools\VsDevCmd.bat -arch=amd64 && ` MKDIR C:\TEMP\WIN3P && ` @@ -76,7 +76,7 @@ RUN C:\BuildTools\Common7\Tools\VsDevCmd.bat -arch=amd64 && ` 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 +ADD http://slproweb.com/download/Win64OpenSSL-1_1_0l.exe C:\TEMP\openssl.exe RUN C:\TEMP\openssl.exe /silent && ` DEL C:\TEMP\openssl.exe diff --git a/build/docker/old/Vagrantfile b/build/docker/old/Vagrantfile deleted file mode 100644 index 5eac6e6865f..00000000000 --- a/build/docker/old/Vagrantfile +++ /dev/null @@ -1,59 +0,0 @@ -# -*- mode: ruby -*- -# vi: set ft=ruby : -# -# 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. - -# Base system bootstrap script -$bootstrap_script = <<__BOOTSTRAP__ -echo "Provisioning defaults" - -sudo apt-get update -y -sudo apt-get upgrade -y - -# Install default packages -sudo apt-get install -y build-essential curl git - -# Install latest Docker version -sudo curl -sSL https://get.docker.io/gpg | sudo apt-key add - -sudo echo "deb http://get.docker.io/ubuntu docker main" > /etc/apt/sources.list.d/docker.list -sudo apt-get update -y -sudo apt-get install -y linux-image-extra-`uname -r` aufs-tools -sudo apt-get install -y lxc-docker - -echo "Finished provisioning defaults" -__BOOTSTRAP__ - -Vagrant.configure("2") do |config| - config.vm.box = "trusty64" - config.vm.box_url = "https://cloud-images.ubuntu.com/vagrant/trusty/current/trusty-server-cloudimg-amd64-vagrant-disk1.box" - config.ssh.forward_agent = true - - config.vm.provider :virtualbox do |vbox| - vbox.customize ["modifyvm", :id, "--memory", "1024"] - vbox.customize ["modifyvm", :id, "--cpus", "2"] - end - - # Setup the default bootstrap script for our ubuntu base box image - config.vm.provision "shell", inline: $bootstrap_script - - # Setup the custom docker image from our Ubuntu Dockerfile - config.vm.provision "docker" do |d| - d.build_image "/vagrant/ubuntu", args: "-t thrift" - end - - # Setup the custom docker image from our Centos Dockerfile - #config.vm.provision "docker" do |d| - # d.build_image "/vagrant/centos", args: "-t thrift-centos" - #end - -end diff --git a/build/docker/old/centos-7.3/Dockerfile b/build/docker/old/centos-7.3/Dockerfile deleted file mode 100644 index ba4c54926fd..00000000000 --- a/build/docker/old/centos-7.3/Dockerfile +++ /dev/null @@ -1,196 +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. - -# Apache Thrift Docker build environment for CentOS -# -# Known missing client libraries: -# - dotnet (will update to 2.0.0 separately) -# - haxe (not in centos) - -FROM centos:7.3.1611 -MAINTAINER Apache Thrift - -RUN yum install -y epel-release - -# General dependencies -RUN yum install -y \ - autoconf \ - bison \ - bison-devel \ - clang \ - clang-analyzer \ - cmake3 \ - curl \ - flex \ - gcc \ - gcc-c++ \ - gdb \ - git \ - libtool \ - m4 \ - make \ - tar \ - unzip \ - valgrind \ - wget && \ - ln -s /usr/bin/cmake3 /usr/bin/cmake && \ - ln -s /usr/bin/cpack3 /usr/bin/cpack && \ - ln -s /usr/bin/ctest3 /usr/bin/ctest - -# C++ dependencies -RUN yum install -y \ - boost-devel-static \ - zlib-devel \ - openssl-devel \ - libevent-devel && \ - cd /usr/lib64 && \ - ln -s libboost_thread-mt.a libboost_thread.a - -# C# Dependencies -RUN yum install -y \ - mono-core \ - mono-devel \ - mono-web-devel \ - mono-extras - -# D Dependencies -RUN yum install -y http://downloads.dlang.org/releases/2.x/2.076.0/dmd-2.076.0-0.fedora.x86_64.rpm xdg-utils -RUN curl -sSL https://github.com/D-Programming-Deimos/openssl/archive/master.tar.gz| tar xz && \ - curl -sSL https://github.com/D-Programming-Deimos/libevent/archive/master.tar.gz| tar xz && \ - mkdir -p /usr/include/dmd/druntime/import/deimos /usr/include/dmd/druntime/import/C && \ - mv libevent-master/deimos/* openssl-master/deimos/* /usr/include/dmd/druntime/import/deimos/ && \ - mv libevent-master/C/* openssl-master/C/* /usr/include/dmd/druntime/import/C/ && \ - rm -rf libevent-master openssl-master - -# Dart -RUN cd /usr/local && \ - wget -q https://storage.googleapis.com/dart-archive/channels/stable/release/1.24.2/sdk/dartsdk-linux-x64-release.zip && \ - unzip -q dartsdk-linux-x64-release.zip && \ - rm dartsdk-linux-x64-release.zip -ENV PATH /usr/local/dart-sdk/bin:$PATH - -# Erlang Dependencies -RUN curl -sSL http://packages.erlang-solutions.com/rpm/centos/erlang_solutions.repo -o /etc/yum.repos.d/erlang_solutions.repo && \ - yum install -y \ - erlang-kernel \ - erlang-erts \ - erlang-stdlib \ - erlang-eunit \ - erlang-rebar \ - erlang-tools - -# GLibC Dependencies -RUN yum install -y glib2-devel - -# Go Dependencies -RUN curl -sSL https://storage.googleapis.com/golang/go1.9.linux-amd64.tar.gz | tar -C /usr/local/ -xz -ENV PATH /usr/local/go/bin:$PATH - -# Haxe Dependencies -# Not in debian/stretch - -# Java Dependencies -RUN yum install -y \ - ant \ - junit \ - ant-junit \ - java-1.8.0-openjdk-devel - -# Lua Dependencies -# Lua in epel is too old (5.1.4, need 5.2) so we get the latest -RUN yum install -y readline-devel && \ - wget -q http://www.lua.org/ftp/lua-5.3.4.tar.gz && \ - tar xzf lua-5.3.4.tar.gz && \ - cd lua-5.3.4 && \ - sed -i 's/CFLAGS= /CFLAGS= -fPIC /g' src/Makefile && \ - make linux && \ - make install && \ - cd .. && \ - rm -rf lua-5* - -# MinGW Dependencies -RUN yum install -y \ - mingw32-binutils \ - mingw32-crt \ - mingw32-nsis - -# Node.js Dependencies -# Work around epel issue where they removed http-parser that nodejs depends on! -RUN yum -y install https://opensource.enda.eu/packages/http-parser-2.7.1-3.el7.x86_64.rpm -RUN yum install -y \ - nodejs \ - npm - -# Ocaml Dependencies -RUN yum install -y \ - ocaml \ - ocaml-ocamldoc && \ - wget -q https://raw.github.com/ocaml/opam/master/shell/opam_installer.sh -O - | sh -s /usr/local/bin && \ - opam init --yes && \ - opam install --yes oasis && \ - echo '. /root/.opam/opam-init/init.sh > /dev/null 2> /dev/null || true' >> ~/.bashrc - -# Perl Dependencies -RUN yum install -y \ - perl \ - perl-version \ - perl-Bit-Vector \ - perl-Class-Accessor \ - perl-ExtUtils-MakeMaker \ - perl-Test-Simple \ - perl-IO-Socket-SSL \ - perl-Net-SSLeay \ - perl-Crypt-SSLeay - -# PHP Dependencies -RUN yum install -y \ - php \ - php-devel \ - php-pear \ - re2c \ - php-phpunit-PHPUnit \ - bzip2 - -# Python Dependencies -RUN yum install -y \ - python \ - python-devel \ - python-pip \ - python-setuptools \ - python34 \ - python34-devel \ - python34-pip \ - python34-setuptools -RUN pip2 install --upgrade pip -RUN pip2 install --upgrade backports.ssl_match_hostname ipaddress setuptools six tornado tornado-testing twisted virtualenv zope-interface -RUN pip3 install --upgrade pip -RUN pip3 install --upgrade backports.ssl_match_hostname ipaddress setuptools six tornado tornado-testing twisted virtualenv zope-interface - -# Ruby Dependencies -RUN yum install -y \ - ruby \ - ruby-devel \ - rubygems && \ - gem install bundler rake - -# Rust -RUN curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain 1.17.0 -ENV PATH /root/.cargo/bin:$PATH - -# Clean up -RUN rm -rf /tmp/* && \ - yum clean all - -ENV THRIFT_ROOT /thrift -RUN mkdir -p $THRIFT_ROOT/src -COPY Dockerfile $THRIFT_ROOT/ -WORKDIR $THRIFT_ROOT/src diff --git a/build/docker/old/debian-jessie/Dockerfile b/build/docker/old/debian-jessie/Dockerfile deleted file mode 100644 index 15e02e9c181..00000000000 --- a/build/docker/old/debian-jessie/Dockerfile +++ /dev/null @@ -1,197 +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. - -# Apache Thrift Docker build environment for Debian -# -# Known missing client libraries: -# - dotnetcore -# - rust - -FROM buildpack-deps:jessie-scm -MAINTAINER Apache Thrift - -ENV DEBIAN_FRONTEND noninteractive - -# Add apt sources -# jessie-backports for cmake and some ruby bits -RUN echo "deb http://ftp.debian.org/debian jessie-backports main" > /etc/apt/sources.list.d/jessie-backports.list - -# Dart -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 && \ - sed -i /etc/apt/sources.list.d/dart_stable.list -e 's/https:/http:/g' - -RUN apt-get update && apt-get install -y --no-install-recommends \ -`# General dependencies` \ - bison \ - build-essential \ - clang \ - debhelper \ - flex \ - pkg-config && \ - apt-get -t jessie-backports install -y --no-install-recommends cmake - -RUN apt-get install -y --no-install-recommends \ -`# C++ dependencies` \ - libboost-dev \ - libboost-filesystem-dev \ - libboost-program-options-dev \ - libboost-system-dev \ - libboost-test-dev \ - libboost-thread-dev \ - libevent-dev \ - libssl-dev \ - qt5-default \ - qtbase5-dev \ - qtbase5-dev-tools - -RUN apt-get install -y --no-install-recommends \ -`# Java dependencies` \ - ant \ - ant-optional \ - openjdk-7-jdk \ - maven - -RUN apt-get install -y --no-install-recommends \ -`# Python dependencies` \ - python-all \ - python-all-dbg \ - python-all-dev \ - python-pip \ - python-setuptools \ - python-twisted \ - python-zope.interface \ - python3-all \ - python3-all-dbg \ - python3-all-dev \ - python3-setuptools \ - python3-pip - -RUN apt-get install -y --no-install-recommends \ -`# Ruby dependencies` \ - ruby \ - ruby-bundler \ - ruby-dev \ -`# Perl dependencies` \ - libbit-vector-perl \ - libclass-accessor-class-perl \ - libcrypt-ssleay-perl \ - libio-socket-ssl-perl \ - libnet-ssleay-perl - -RUN apt-get -t jessie-backports install -y ruby-bundler -RUN apt-get install -y --no-install-recommends \ -`# Php dependencies` \ - php5 \ - php5-dev \ - php5-cli \ - php-pear \ - re2c \ - phpunit \ -`# GlibC dependencies` \ - libglib2.0-dev - -RUN apt-get update && apt-get install -y --no-install-recommends \ -`# Erlang dependencies` \ - erlang-base \ - erlang-eunit \ - erlang-dev \ - erlang-tools \ - rebar - -RUN apt-get update && apt-get install -y --no-install-recommends \ -`# Haxe dependencies` \ - neko \ - neko-dev \ - libneko0 - -RUN apt-get update && apt-get install -y --no-install-recommends \ -`# Node.js dependencies` \ - nodejs \ - nodejs-dev \ - nodejs-legacy \ - npm - -RUN apt-get update && apt-get install -y --no-install-recommends \ -`# D dependencies` \ - xdg-utils \ -`# Dart dependencies` \ - dart \ -`# Lua dependencies` \ - lua5.2 \ - lua5.2-dev \ -`# MinGW dependencies` \ - mingw32 \ - mingw32-binutils \ -`# mingw32-runtime` \ - nsis \ -`# Clean up` \ - && rm -rf /var/cache/apt/* && \ - rm -rf /var/lib/apt/lists/* && \ - rm -rf /tmp/* && \ - rm -rf /var/tmp/* - -# Ruby -RUN gem install bundler --no-ri --no-rdoc - -# Python optional dependencies -RUN pip2 install -U ipaddress backports.ssl_match_hostname tornado -RUN pip3 install -U backports.ssl_match_hostname tornado - -# Go -RUN curl -sSL https://storage.googleapis.com/golang/go1.4.3.linux-amd64.tar.gz | tar -C /usr/local/ -xz -ENV PATH /usr/local/go/bin:$PATH - -# Haxe -RUN mkdir -p /usr/lib/haxe && \ - wget -O - https://github.com/HaxeFoundation/haxe/releases/download/3.2.1/haxe-3.2.1-linux64.tar.gz | \ - tar -C /usr/lib/haxe --strip-components=1 -xz && \ - ln -s /usr/lib/haxe/haxe /usr/bin/haxe && \ - ln -s /usr/lib/haxe/haxelib /usr/bin/haxelib && \ - mkdir -p /usr/lib/haxe/lib && \ - chmod -R 777 /usr/lib/haxe/lib && \ - haxelib setup /usr/lib/haxe/lib && \ - haxelib install hxcpp - -# D -RUN curl -sSL http://downloads.dlang.org/releases/2.x/2.070.0/dmd_2.070.0-0_amd64.deb -o /tmp/dmd_2.070.0-0_amd64.deb && \ - dpkg -i /tmp/dmd_2.070.0-0_amd64.deb && \ - rm /tmp/dmd_2.070.0-0_amd64.deb && \ - curl -sSL https://github.com/D-Programming-Deimos/openssl/archive/master.tar.gz| tar xz && \ - curl -sSL https://github.com/D-Programming-Deimos/libevent/archive/master.tar.gz| tar xz && \ - mkdir -p /usr/include/dmd/druntime/import/deimos /usr/include/dmd/druntime/import/C && \ - mv libevent-master/deimos/* openssl-master/deimos/* /usr/include/dmd/druntime/import/deimos/ && \ - mv libevent-master/C/* openssl-master/C/* /usr/include/dmd/druntime/import/C/ && \ - rm -rf libevent-master openssl-master && \ - echo 'gcc -Wl,--no-as-needed $*' > /usr/local/bin/gcc-dmd && \ - chmod 755 /usr/local/bin/gcc-dmd && \ - echo 'CC=/usr/local/bin/gcc-dmd' >> /etc/dmd.conf - -# Dart -ENV PATH /usr/lib/dart/bin:$PATH - -# OCaml -RUN echo 'deb http://ppa.launchpad.net/avsm/ppa/ubuntu trusty main' > /etc/apt/sources.list.d/avsm-official-ocaml.list && \ - gpg --keyserver keyserver.ubuntu.com --recv 61707B09 && \ - gpg --export --armor 61707B09 | apt-key add - && \ - apt-get update && \ - apt-get install -y ocaml opam && \ - opam init && \ - opam install oasis - -# Force utf8 locale to successfully build Haskell tf-random -ENV LC_ALL C.UTF-8 - -ENV THRIFT_ROOT /thrift -RUN mkdir -p $THRIFT_ROOT/src -COPY Dockerfile $THRIFT_ROOT/ -WORKDIR $THRIFT_ROOT/src diff --git a/build/docker/old/debian-stretch/Dockerfile b/build/docker/old/debian-stretch/Dockerfile deleted file mode 100644 index f584bba9a96..00000000000 --- a/build/docker/old/debian-stretch/Dockerfile +++ /dev/null @@ -1,225 +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. - -# Apache Thrift Docker build environment for Debian Stretch -# -# Known issues: -# - d: deimos for libevent and openssl disabled - build errors -# - dotnetcore, because netcore is for 1.0.0-preview and 2.0.0 is out -# - rust: cargo not in debian repo - perhaps not needed? - -FROM buildpack-deps:stretch-scm -MAINTAINER Apache Thrift - -ENV DEBIAN_FRONTEND noninteractive - -### Add apt repos - -RUN apt-get update && apt-get install -y --no-install-recommends apt apt-transport-https curl wget apt-utils - -# D -RUN wget http://master.dl.sourceforge.net/project/d-apt/files/d-apt.list -O /etc/apt/sources.list.d/d-apt.list && \ - apt-get update && apt-get -y --allow-unauthenticated install --reinstall d-apt-keyring - -# Dart -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 && \ - sed -i /etc/apt/sources.list.d/dart_stable.list -e 's/https:/http:/g' - -# dotnet (core) 2.0.0 - project isn't ready for this yet: -# RUN curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > /etc/apt/trusted.gpg.d/microsoft.gpg && \ -# echo "deb [arch=amd64] https://packages.microsoft.com/repos/microsoft-ubuntu-xenial-prod xenial main" > /etc/apt/sources.list.d/dotnetdev.list - -# node.js (this step runs apt-get update internally) -RUN curl -sL https://deb.nodesource.com/setup_8.x | bash - - -### install general dependencies -RUN apt-get install -y --no-install-recommends \ -`# General dependencies` \ - bash-completion \ - bison \ - build-essential \ - clang \ - cmake \ - debhelper \ - flex \ - gdb \ - ninja-build \ - pkg-config \ - valgrind \ - vim - - -### languages - -RUN apt-get install -y --no-install-recommends \ -`# C++ dependencies` \ - libboost-dev \ - libboost-filesystem-dev \ - libboost-program-options-dev \ - libboost-system-dev \ - libboost-test-dev \ - libboost-thread-dev \ - libevent-dev \ - libssl-dev \ - qt5-default \ - qtbase5-dev \ - qtbase5-dev-tools - -RUN apt-get install -y --no-install-recommends \ -`# D dependencies` \ - dmd-bin \ - libevent-dev \ - libssl-dev \ - xdg-utils -# libevent deimos disabled - build errors -# RUN 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 -# openssl deimos doesn't work with openssl-1.1.0 - disabling it for now: -# RUN curl -sSL https://github.com/D-Programming-Deimos/openssl/archive/master.tar.gz| tar xz && \ -# mv openssl-master/deimos/* /usr/include/dmd/druntime/import/deimos/ && \ -# mv openssl-master/C/* /usr/include/dmd/druntime/import/C/ && \ -# rm -rf openssl-master - -RUN apt-get install -y --no-install-recommends \ -`# Dart dependencies` \ - dart -ENV PATH /usr/lib/dart/bin:$PATH - -# project isn't ready for this quite yet: -# RUN apt-get install -y --no-install-recommends \ -# `# dotnet core dependencies` \ -# dotnet-sdk-8.0 \ -# dotnet-runtime-8.0 \ -# aspnetcore-runtime-8.0 \ -# dotnet-apphost-pack-8.0 - -RUN apt-get install -y --no-install-recommends \ -`# Erlang dependencies` \ - erlang-base \ - erlang-eunit \ - erlang-dev \ - erlang-tools \ - rebar - -RUN apt-get install -y --no-install-recommends \ -`# GlibC dependencies` \ - libglib2.0-dev - -RUN apt-get install -y --no-install-recommends \ -`# golang (go) dependencies` \ - golang-go - -RUN apt-get install -y --no-install-recommends \ -`# Haxe dependencies` \ - haxe \ - neko \ - neko-dev -RUN haxelib setup --always /usr/share/haxe/lib && \ - haxelib install --always hxcpp - -RUN apt-get install -y --no-install-recommends \ -`# Java dependencies` \ - ant \ - ant-optional \ - openjdk-8-jdk \ - maven - -RUN apt-get install -y --no-install-recommends \ -`# Lua dependencies` \ - lua5.2 \ - lua5.2-dev -# https://bugs.launchpad.net/ubuntu/+source/lua5.3/+bug/1707212 -# same for debian stretch -# lua5.3 does not install alternatives so stick with 5.2 here - -RUN apt-get install -y --no-install-recommends \ -`# Node.js dependencies` \ - nodejs - -RUN apt-get install -y --no-install-recommends \ -`# OCaml dependencies` \ - ocaml \ - opam && \ - opam init --yes && \ - opam install --yes oasis - -RUN apt-get install -y --no-install-recommends \ -`# Perl dependencies` \ - libbit-vector-perl \ - libclass-accessor-class-perl \ - libcrypt-ssleay-perl \ - libio-socket-ssl-perl \ - libnet-ssleay-perl - -RUN apt-get install -y --no-install-recommends \ -`# Php dependencies` \ - php7.0 \ - php7.0-cli \ - php7.0-dev \ - php-pear \ - re2c \ - phpunit - -RUN apt-get install -y --no-install-recommends \ -`# Python dependencies` \ - python-all \ - python-all-dbg \ - python-all-dev \ - python-backports.ssl-match-hostname \ - python-ipaddress \ - python-pip \ - python-setuptools \ - python-six \ - python-tornado \ - python-twisted \ - python-wheel \ - python-zope.interface \ - python3-all \ - python3-all-dbg \ - python3-all-dev \ - python3-setuptools \ - python3-six \ - python3-tornado \ - python3-twisted \ - python3-wheel \ - python3-zope.interface && \ - pip install --upgrade backports.ssl_match_hostname - -RUN apt-get install -y --no-install-recommends \ -`# Ruby dependencies` \ - ruby \ - ruby-dev \ - ruby-bundler -RUN gem install bundler --no-ri --no-rdoc - -RUN apt-get install -y --no-install-recommends \ -`# Rust dependencies` \ - rustc - -# Update anything else left hanging -RUN apt-get dist-upgrade -y - -# Clean up -RUN rm -rf /var/cache/apt/* && \ - rm -rf /var/lib/apt/lists/* && \ - rm -rf /tmp/* && \ - rm -rf /var/tmp/* - -ENV THRIFT_ROOT /thrift -RUN mkdir -p $THRIFT_ROOT/src -COPY Dockerfile $THRIFT_ROOT/ -WORKDIR $THRIFT_ROOT/src diff --git a/build/docker/old/ubuntu-artful/Dockerfile b/build/docker/old/ubuntu-artful/Dockerfile deleted file mode 100644 index f94b70086b5..00000000000 --- a/build/docker/old/ubuntu-artful/Dockerfile +++ /dev/null @@ -1,260 +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. - -# -# Apache Thrift Docker build environment for Ubuntu Artful -# Using all stock Ubuntu Artful packaging except for: -# - cpp: stock boost 1.62 in artful has a nasty bug so we use stock boost 1.63 -# - d: dmd does not come with Ubuntu -# - dart: does not come with Ubuntu. Pinned to last 1.x release -# - dotnet: does not come with Ubuntu -# - haxe: version 3.4.2 that comes with Ubuntu cores in our CI build -# - go: artful comes with 1.9, we want the latest (supported) -# - nodejs: want v8, artful comes with v6 -# - -FROM buildpack-deps:artful-scm -MAINTAINER Apache Thrift -ENV DEBIAN_FRONTEND noninteractive - -### Add apt repos - -RUN apt-get update && \ - apt-get dist-upgrade -y && \ - apt-get install -y --no-install-recommends \ - apt \ - apt-transport-https \ - apt-utils \ - curl \ - dirmngr \ - software-properties-common \ - wget - -# Dart -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 && \ - echo "deb [arch=amd64] https://packages.microsoft.com/repos/microsoft-ubuntu-artful-prod artful main" > \ - /etc/apt/sources.list.d/dotnetdev.list - -# haxe (https://haxe.org/download/linux/) -RUN add-apt-repository ppa:haxe/releases -y - -# node.js -RUN curl -sL https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add - && \ - echo "deb https://deb.nodesource.com/node_8.x artful main" | tee /etc/apt/sources.list.d/nodesource.list - -### install general dependencies -RUN apt-get update && apt-get install -y --no-install-recommends \ -`# General dependencies` \ - bash-completion \ - bison \ - build-essential \ - clang \ - cmake \ - debhelper \ - flex \ - gdb \ - llvm \ - ninja-build \ - pkg-config \ - valgrind \ - vim -ENV PATH /usr/lib/llvm-3.8/bin:$PATH - -# boost-1.62 has a terrible bug in boost::test, see https://svn.boost.org/trac10/ticket/12507 -RUN apt-get install -y --no-install-recommends \ -`# C++ dependencies` \ - libboost1.63-all-dev \ - libevent-dev \ - libssl-dev \ - qt5-default \ - qtbase5-dev \ - qtbase5-dev-tools - -ENV SBCL_VERSION 1.4.5 -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 && \ - tar xjf sbcl-${SBCL_VERSION}-x86-64-linux-binary.tar.bz2 && \ - cd sbcl-${SBCL_VERSION}-x86-64-linux && \ - ./install.sh && \ - sbcl --version && \ - rm -rf sbcl* - -ENV D_VERSION 2.080.0 -ENV DMD_DEB dmd_2.080.0-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/D-Programming-Deimos/openssl/archive/master.tar.gz| tar xz && \ - mv openssl-master/deimos/* /usr/include/dmd/druntime/import/deimos/ && \ - mv openssl-master/C/* /usr/include/dmd/druntime/import/C/ && \ - rm -rf openssl-master - -RUN apt-get install -y --no-install-recommends \ -`# Dart dependencies` \ - dart=$DART_VERSION -ENV PATH /usr/lib/dart/bin:$PATH - -RUN apt-get install -y --no-install-recommends \ -`# dotnet core dependencies` \ - dotnet-sdk-8.0 \ - dotnet-runtime-8.0 \ - aspnetcore-runtime-8.0 \ - dotnet-apphost-pack-8.0 - -RUN apt-get install -y --no-install-recommends \ -`# Erlang dependencies` \ - erlang-base \ - erlang-eunit \ - erlang-dev \ - erlang-tools \ - rebar - -RUN apt-get install -y --no-install-recommends \ -`# GlibC dependencies` \ - libglib2.0-dev - -# golang -ENV GOLANG_VERSION 1.10 -ENV GOLANG_DOWNLOAD_URL https://golang.org/dl/go$GOLANG_VERSION.linux-amd64.tar.gz -ENV GOLANG_DOWNLOAD_SHA256 b5a64335f1490277b585832d1f6c7f8c6c11206cba5cd3f771dcb87b98ad1a33 -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 && \ - ln -s /usr/local/go/bin/go /usr/local/bin && \ - rm golang.tar.gz - -RUN apt-get install -y --no-install-recommends \ -`# Haxe dependencies` \ - haxe \ - neko \ - neko-dev && \ - haxelib setup --always /usr/share/haxe/lib && \ - haxelib install --always hxcpp 2>&1 > /dev/null - -RUN apt-get install -y --no-install-recommends \ -`# Java dependencies` \ - ant \ - ant-optional \ - openjdk-8-jdk \ - maven - -RUN apt-get install -y --no-install-recommends \ -`# Lua dependencies` \ - lua5.2 \ - lua5.2-dev -# https://bugs.launchpad.net/ubuntu/+source/lua5.3/+bug/1707212 -# lua5.3 does not install alternatives! -# need to update our luasocket code, lua doesn't have luaL_openlib any more - -RUN apt-get install -y --no-install-recommends \ -`# Node.js dependencies` \ - nodejs - -# Test dependencies for running puppeteer -RUN apt-get install -y --no-install-recommends \ -`# JS dependencies` \ - libxss1 - -RUN apt-get install -y --no-install-recommends \ -`# OCaml dependencies` \ - ocaml \ - opam && \ - opam init --yes && \ - opam install --yes oasis - -RUN apt-get install -y --no-install-recommends \ -`# Perl dependencies` \ - libbit-vector-perl \ - libclass-accessor-class-perl \ - libcrypt-ssleay-perl \ - libio-socket-ssl-perl \ - libnet-ssleay-perl - -RUN apt-get install -y --no-install-recommends \ -`# Php dependencies` \ - php \ - php-cli \ - php-dev \ - php-pear \ - re2c \ - composer - -RUN apt-get install -y --no-install-recommends \ -`# Python dependencies` \ - python-all \ - python-all-dbg \ - python-all-dev \ - python-ipaddress \ - python-pip \ - python-setuptools \ - python-six \ - python-tornado \ - python-twisted \ - python-wheel \ - python-zope.interface && \ - pip install --upgrade backports.ssl_match_hostname - -RUN apt-get install -y --no-install-recommends \ -`# Python3 dependencies` \ - python3-all \ - python3-all-dbg \ - python3-all-dev \ - python3-pip \ - python3-setuptools \ - python3-six \ - python3-tornado \ - python3-twisted \ - python3-wheel \ - python3-zope.interface - -RUN apt-get install -y --no-install-recommends \ -`# Ruby dependencies` \ - ruby \ - ruby-dev \ - ruby-bundler - -RUN apt-get install -y --no-install-recommends \ -`# Rust dependencies` \ - cargo \ - rustc - -RUN apt-get install -y --no-install-recommends \ -`# Static Code Analysis dependencies` \ - cppcheck \ - sloccount && \ - pip install flake8 - -# Clean up -RUN rm -rf /var/cache/apt/* && \ - rm -rf /var/lib/apt/lists/* && \ - rm -rf /tmp/* && \ - rm -rf /var/tmp/* - -ENV THRIFT_ROOT /thrift -RUN mkdir -p $THRIFT_ROOT/src -COPY Dockerfile $THRIFT_ROOT/ -WORKDIR $THRIFT_ROOT/src diff --git a/build/docker/old/ubuntu-disco/Dockerfile b/build/docker/old/ubuntu-disco/Dockerfile deleted file mode 100644 index 39642cf2b00..00000000000 --- a/build/docker/old/ubuntu-disco/Dockerfile +++ /dev/null @@ -1,296 +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. - -# -# Apache Thrift Docker build environment for Ubuntu Disco -# with some updated packages. -# - -FROM buildpack-deps:disco-scm -MAINTAINER Apache Thrift -ENV DEBIAN_FRONTEND noninteractive - -### Add apt repos - -RUN apt-get update && \ - apt-get dist-upgrade -y && \ - apt-get install -y --no-install-recommends \ - apt \ - apt-transport-https \ - apt-utils \ - curl \ - dirmngr \ - software-properties-common \ - wget - -# Dart -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 - -# dotnet (netcore) -RUN curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > /etc/apt/trusted.gpg.d/microsoft.gpg && \ - wget -q -O /etc/apt/sources.list.d/microsoft-prod.list https://packages.microsoft.com/config/ubuntu/18.04/prod.list && \ - chown root:root /etc/apt/trusted.gpg.d/microsoft.gpg && \ - chown root:root /etc/apt/sources.list.d/microsoft-prod.list - -# erlang -RUN wget -O- https://packages.erlang-solutions.com/ubuntu/erlang_solutions.asc | apt-key add - && \ - echo "deb https://packages.erlang-solutions.com/ubuntu disco contrib" | tee /etc/apt/sources.list.d/erlang.list - -# node.js -RUN curl -sL https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add - && \ - echo "deb https://deb.nodesource.com/node_10.x disco main" | tee /etc/apt/sources.list.d/nodesource.list - -### install general dependencies -RUN apt-get update && apt-get install -y --no-install-recommends \ - `# General dependencies` \ - bash-completion \ - bison \ - build-essential \ - clang \ - cmake \ - debhelper \ - flex \ - gdb \ - libasound2 \ - libatk-bridge2.0-0 \ - libgtk-3-0 \ - llvm \ - ninja-build \ - pkg-config \ - unzip \ - valgrind \ - vim -ENV PATH /usr/lib/llvm-6.0/bin:$PATH - -# lib/as3 (ActionScript) -RUN mkdir -p /usr/local/adobe/flex/4.6 && \ - cd /usr/local/adobe/flex/4.6 && \ - wget -q "http://download.macromedia.com/pub/flex/sdk/flex_sdk_4.6.zip" && \ - unzip flex_sdk_4.6.zip -ENV FLEX_HOME /usr/local/adobe/flex/4.6 - -RUN apt-get install -y --no-install-recommends \ - `# C++ dependencies` \ - libboost-all-dev \ - libevent-dev \ - libssl-dev \ - qt5-default \ - qtbase5-dev \ - qtbase5-dev-tools - -ENV SBCL_VERSION 1.5.3 -RUN \ - `# Common Lisp (sbcl) dependencies` \ - curl --version && \ - 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 && \ - sbcl --version && \ - cd .. && \ - rm -rf sbcl* - -ENV D_VERSION 2.087.0 -ENV DMD_DEB dmd_2.087.0-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 && \ - 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.7.2-1 -RUN apt-get install -y --no-install-recommends \ - `# Dart dependencies` \ - dart=$DART_VERSION -ENV PATH /usr/lib/dart/bin:$PATH - -RUN apt-get install -y --no-install-recommends \ - `# dotnet core dependencies` \ - dotnet-sdk-8.0 \ - dotnet-runtime-8.0 \ - aspnetcore-runtime-8.0 \ - dotnet-apphost-pack-8.0 - -RUN apt-get install -y --no-install-recommends \ - `# Erlang dependencies` \ - erlang && \ - wget https://s3.amazonaws.com/rebar3/rebar3 -O /usr/bin/rebar3 && \ - chmod 755 /usr/bin/rebar3 && \ - rebar3 --version - -RUN apt-get install -y --no-install-recommends \ - `# GlibC dependencies` \ - libglib2.0-dev - -# golang -ENV GOLANG_VERSION 1.19 -ENV GOLANG_DOWNLOAD_URL https://go.dev/dl/go$GOLANG_VERSION.linux-amd64.tar.gz -ENV GOLANG_DOWNLOAD_SHA256 464b6b66591f6cf055bc5df90a9750bf5fbc9d038722bb84a9d56a2bea974be6 -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 && \ - ln -s /usr/local/go/bin/go /usr/local/bin && \ - rm golang.tar.gz - -RUN apt-get install -y --no-install-recommends \ - `# Haxe dependencies` \ - haxe \ - neko \ - neko-dev && \ - haxelib setup --always /usr/share/haxe/lib && \ - haxelib install --always hxcpp 2>&1 > /dev/null - -ENV GRADLE_VERSION="8.4" -RUN apt-get install -y --no-install-recommends \ - `# Java dependencies` \ - ant \ - ant-optional \ - maven \ - openjdk-11-jdk-headless && \ - `# Gradle` \ - wget https://services.gradle.org/distributions/gradle-$GRADLE_VERSION-bin.zip -q -O /tmp/gradle-$GRADLE_VERSION-bin.zip && \ - (echo "3e1af3ae886920c3ac87f7a91f816c0c7c436f276a6eefdb3da152100fef72ae /tmp/gradle-$GRADLE_VERSION-bin.zip" | sha256sum -c -) && \ - unzip -d /tmp /tmp/gradle-$GRADLE_VERSION-bin.zip && \ - mv /tmp/gradle-$GRADLE_VERSION /usr/local/gradle && \ - ln -s /usr/local/gradle/bin/gradle /usr/local/bin - -RUN apt-get install -y --no-install-recommends \ - `# Lua dependencies` \ - lua5.2 \ - lua5.2-dev -# https://bugs.launchpad.net/ubuntu/+source/lua5.3/+bug/1707212 -# lua5.3 does not install alternatives! -# need to update our luasocket code, lua doesn't have luaL_openlib any more - -RUN apt-get install -y --no-install-recommends \ - `# Node.js dependencies` \ - nodejs - -# Test dependencies for running puppeteer -RUN apt-get install -y --no-install-recommends \ - `# JS dependencies` \ - libxss1 \ - libxtst6 - -# does not work on disco? -# RUN apt-get install -y --no-install-recommends \ -# `# OCaml dependencies` \ -# ocaml \ -# opam && \ -# opam init --yes && \ -# opam install --yes oasis - -RUN apt-get install -y --no-install-recommends \ - `# Perl dependencies` \ - libbit-vector-perl \ - libclass-accessor-class-perl \ - libcrypt-ssleay-perl \ - libio-socket-ssl-perl \ - libnet-ssleay-perl \ - libtest-exception-perl - -RUN apt-get install -y --no-install-recommends \ - `# Php dependencies` \ - php \ - php-cli \ - php-dev \ - php-json \ - php-pear \ - re2c \ - composer - -RUN apt-get install -y --no-install-recommends \ - `# Python dependencies` \ - python-all \ - python-all-dbg \ - python-all-dev \ - python-ipaddress \ - python-pip \ - python-setuptools \ - python-six \ - python-tornado \ - python-twisted \ - python-wheel \ - python-zope.interface && \ - pip install --upgrade backports.ssl_match_hostname - -RUN apt-get install -y --no-install-recommends \ - `# Python3 dependencies` \ - python3-all \ - python3-all-dbg \ - python3-all-dev \ - python3-pip \ - python3-setuptools \ - python3-six \ - python3-tornado \ - python3-twisted \ - python3-wheel \ - python3-zope.interface - -RUN apt-get install -y --no-install-recommends \ - `# Ruby dependencies` \ - ruby \ - ruby-dev \ - ruby-bundler - -# Rust dependencies -RUN curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain 1.65.0 -y -ENV PATH /root/.cargo/bin:$PATH - -# Swift on Linux for cross tests -# does not work on disco -# 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 - -# Locale(s) for cpp unit tests -RUN apt-get install -y --no-install-recommends \ - `# Locale dependencies` \ - locales && \ - locale-gen en_US.UTF-8 && \ - locale-gen de_DE.UTF-8 && \ - update-locale - -# cppcheck-1.82 has a nasty cpp parser bug, so we're using something newer -# don't need this on disco, nobody uses it -# RUN apt-get install -y --no-install-recommends \ -# `# Static Code Analysis dependencies` \ -# cppcheck \ -# sloccount && \ -# pip install flake8 && \ -# wget -q "https://launchpad.net/ubuntu/+source/cppcheck/1.83-2/+build/14874703/+files/cppcheck_1.83-2_amd64.deb" && \ -# dpkg -i cppcheck_1.83-2_amd64.deb && \ -# rm cppcheck_1.83-2_amd64.deb - -# Clean up -RUN rm -rf /var/cache/apt/* && \ - rm -rf /var/lib/apt/lists/* && \ - rm -rf /tmp/* && \ - rm -rf /var/tmp/* - -ENV THRIFT_ROOT /thrift -RUN mkdir -p $THRIFT_ROOT/src -COPY Dockerfile $THRIFT_ROOT/ -WORKDIR $THRIFT_ROOT/src diff --git a/build/docker/old/ubuntu-trusty/Dockerfile b/build/docker/old/ubuntu-trusty/Dockerfile deleted file mode 100644 index 89f683e4bcf..00000000000 --- a/build/docker/old/ubuntu-trusty/Dockerfile +++ /dev/null @@ -1,235 +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. - -# -# Apache Thrift Docker build environment for Ubuntu Trusty -# Using all stock Ubuntu Trusty packaging except for: -# - d: does not come with Ubuntu so we're installing 2.070.0 -# - dart: does not come with Ubuntu so we're installing 1.20.1 -# - dotnetcore, disabled because netcore is for 1.0.0-preview and 2.0.0 is out -# - haxe, disabled because the distro comes with 3.0.0 and it cores while installing -# - node.js, disabled because it is at 0.10.0 in the distro which is too old (need 4+) -# - ocaml, disabled because it fails to install properly -# - -FROM buildpack-deps:trusty-scm -MAINTAINER Apache Thrift -ENV DEBIAN_FRONTEND noninteractive - -### Add apt repos - -RUN apt-get update && \ - apt-get dist-upgrade -y && \ - apt-get install -y --no-install-recommends \ - apt \ - apt-transport-https \ - apt-utils \ - curl \ - dirmngr \ - software-properties-common \ - wget - -# D -RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys EBCF975E5BA24D5E && \ - wget http://master.dl.sourceforge.net/project/d-apt/files/d-apt.list -O /etc/apt/sources.list.d/d-apt.list && \ - wget -qO - https://dlang.org/d-keyring.gpg | apt-key add - - -# Dart -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 - -RUN apt-get update && apt-get install -y --no-install-recommends \ -`# General dependencies` \ - bash-completion \ - bison \ - build-essential \ - clang \ - cmake \ - debhelper \ - flex \ - gdb \ - llvm \ - ninja-build \ - pkg-config \ - valgrind \ - vim -ENV PATH /usr/lib/llvm-3.8/bin:$PATH - -RUN apt-get install -y --no-install-recommends \ -`# C++ dependencies` \ - libboost-all-dev \ - libevent-dev \ - libssl-dev \ - qt5-default \ - qtbase5-dev \ - qtbase5-dev-tools - -RUN apt-get install -y --no-install-recommends \ -`# D dependencies` \ - dmd-bin=2.070.2-0 \ - libphobos2-dev=2.070.2-0 \ - dub \ - dfmt \ - dscanner \ - xdg-utils -RUN 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 -RUN curl -sSL https://github.com/D-Programming-Deimos/openssl/archive/master.tar.gz| tar xz && \ - mv openssl-master/deimos/* /usr/include/dmd/druntime/import/deimos/ && \ - mv openssl-master/C/* /usr/include/dmd/druntime/import/C/ && \ - rm -rf openssl-master - -RUN apt-get install -y --no-install-recommends \ -`# Dart dependencies` \ - dart=1.20.1-1 -ENV PATH /usr/lib/dart/bin:$PATH - -RUN apt-get install -y --no-install-recommends \ -`# Erlang dependencies` \ - erlang-base \ - erlang-eunit \ - erlang-dev \ - erlang-tools \ - rebar - -RUN apt-get install -y --no-install-recommends \ -`# GlibC dependencies` \ - libglib2.0-dev - -# golang -ENV GOLANG_VERSION 1.7.6 -ENV GOLANG_DOWNLOAD_URL https://golang.org/dl/go$GOLANG_VERSION.linux-amd64.tar.gz -ENV GOLANG_DOWNLOAD_SHA256 ad5808bf42b014c22dd7646458f631385003049ded0bb6af2efc7f1f79fa29ea -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 && \ - ln -s /usr/local/go/bin/go /usr/local/bin && \ - rm golang.tar.gz - -# disabled because it cores while installing -# RUN apt-get install -y --no-install-recommends \ -# `# Haxe dependencies` \ -# haxe \ -# neko \ -# neko-dev && \ -# haxelib setup /usr/share/haxe/lib && \ -# haxelib install hxcpp 3.2.102 - -RUN apt-get install -y --no-install-recommends \ -`# Java dependencies` \ - ant \ - ant-optional \ - openjdk-7-jdk \ - maven - -RUN apt-get install -y --no-install-recommends \ -`# Lua dependencies` \ - lua5.1 \ - lua5.1-dev - -# disabled because it is too old -# RUN apt-get install -y --no-install-recommends \ -# `# Node.js dependencies` \ -# nodejs \ -# npm - -# disabled because it fails to install properly -# RUN apt-get install -y --no-install-recommends \ -# `# OCaml dependencies` \ -# ocaml \ -# opam && \ -# opam init --yes && \ -# opam install --yes oasis - -RUN apt-get install -y --no-install-recommends \ -`# Perl dependencies` \ - libbit-vector-perl \ - libclass-accessor-class-perl \ - libcrypt-ssleay-perl \ - libio-socket-ssl-perl \ - libnet-ssleay-perl - -RUN apt-get install -y --no-install-recommends \ -`# Php dependencies` \ - php5 \ - php5-cli \ - php5-dev \ - php-pear \ - re2c && \ - wget https://getcomposer.org/installer -O - -q | php -- --quiet --install-dir=/usr/local/bin/ --filename=composer - -RUN apt-get install -y --no-install-recommends \ -`# Python dependencies` \ - python-all \ - python-all-dbg \ - python-all-dev \ - python-pip \ - python-setuptools \ - python-six \ - python-twisted \ - python-wheel \ - python-zope.interface \ - python3-all \ - python3-all-dbg \ - python3-all-dev \ - python3-pip \ - python3-setuptools \ - python3-six \ - python3-wheel \ - python3-zope.interface && \ - pip install -U ipaddress backports.ssl_match_hostname tornado && \ - pip3 install -U backports.ssl_match_hostname tornado -# installing tornado by pip/pip3 instead of debian package -# if we install the debian package, the build fails in py2 - -RUN apt-get install -y --no-install-recommends \ -`# Ruby dependencies` \ - ruby \ - ruby-dev \ - ruby-bundler -RUN gem install bundler --no-ri --no-rdoc - -RUN apt-get install -y --no-install-recommends \ -`# Rust dependencies` \ - cargo \ - rustc - -RUN apt-get install -y --no-install-recommends \ -`# Static Code Analysis dependencies` \ - cppcheck \ - sloccount && \ - pip install flake8 - -# Install BouncyCastle provider to fix Java builds issues with JDK 7 -# Builds accessing repote repositories fail as seen here: https://github.com/travis-ci/travis-ci/issues/8503 -RUN apt-get install -y --no-install-recommends \ -`# BouncyCastle JCE Provider dependencies` \ - libbcprov-java && \ - ln -s /usr/share/java/bcprov.jar /usr/lib/jvm/java-7-openjdk-amd64/jre/lib/ext/bcprov.jar && \ - awk -F . -v OFS=. 'BEGIN{n=2}/^security\.provider/ {split($3, posAndEquals, "=");$3=n++"="posAndEquals[2];print;next} 1' /etc/java-7-openjdk/security/java.security > /tmp/java.security && \ - echo "security.provider.1=org.bouncycastle.jce.provider.BouncyCastleProvider" >> /tmp/java.security && \ - mv /tmp/java.security /etc/java-7-openjdk/security/java.security - -# Clean up -RUN rm -rf /var/cache/apt/* && \ - rm -rf /var/lib/apt/lists/* && \ - rm -rf /tmp/* && \ - rm -rf /var/tmp/* - -ENV THRIFT_ROOT /thrift -RUN mkdir -p $THRIFT_ROOT/src -COPY Dockerfile $THRIFT_ROOT/ -WORKDIR $THRIFT_ROOT/src diff --git a/build/docker/old/ubuntu-xenial/Dockerfile b/build/docker/old/ubuntu-xenial/Dockerfile deleted file mode 100644 index d9d87ccaea3..00000000000 --- a/build/docker/old/ubuntu-xenial/Dockerfile +++ /dev/null @@ -1,273 +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. - -# -# 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.087.0 for coverage -# - dart: does not come with Ubuntu so we're installing 2.0.0-1 for coverage -# - dotnet: does not come with Ubuntu -# - 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 10.x -# - ocaml: causes stack overflow error, just started March 2018 not sure why -# - -FROM buildpack-deps:xenial-scm -MAINTAINER Apache Thrift -ENV DEBIAN_FRONTEND noninteractive - -### Add apt repos - -RUN apt-get update && \ - apt-get dist-upgrade -y && \ - apt-get install -y --no-install-recommends \ - apt \ - apt-transport-https \ - apt-utils \ - curl \ - software-properties-common \ - wget && \ - - # Dart - 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 && \ - - # dotnet (core) - curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > /etc/apt/trusted.gpg.d/microsoft.gpg && \ - echo "deb [arch=amd64] https://packages.microsoft.com/repos/microsoft-ubuntu-xenial-prod xenial main" > \ - /etc/apt/sources.list.d/dotnetdev.list && \ - - # node.js - curl -sL https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add - && \ - echo "deb https://deb.nodesource.com/node_10.x xenial main" | tee /etc/apt/sources.list.d/nodesource.list && \ - - # ruby 2.4 - apt-add-repository ppa:brightbox/ruby-ng - -### install general dependencies -RUN apt-get update && apt-get install -y --no-install-recommends \ - `# General dependencies` \ - bash-completion \ - bison \ - build-essential \ - clang \ - cmake \ - debhelper \ - flex \ - gdb \ - llvm \ - ninja-build \ - pkg-config \ - valgrind \ - vim -ENV PATH /usr/lib/llvm-3.8/bin:$PATH - -### languages - -# TODO: "apt-get install" without "apt-get update" in the same "RUN" step can cause cache issues if modified later. -# See https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#run -RUN apt-get install -y --no-install-recommends \ - `# C++ dependencies` \ - libboost-dev \ - libboost-filesystem-dev \ - libboost-program-options-dev \ - libboost-system-dev \ - libboost-test-dev \ - libboost-thread-dev \ - libevent-dev \ - libssl-dev \ - qt5-default \ - qtbase5-dev \ - qtbase5-dev-tools - -ENV D_VERSION 2.087.0 -ENV DMD_DEB dmd_2.087.0-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 && \ - 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 'v1.1.6+1.0.1g' https://github.com/D-Programming-Deimos/openssl.git deimos-openssl-1.0.1g && \ - mv deimos-openssl-1.0.1g/deimos/* /usr/include/dmd/druntime/import/deimos/ && \ - mv deimos-openssl-1.0.1g/C/* /usr/include/dmd/druntime/import/C/ && \ - rm -rf deimos-openssl-1.0.1g - -ENV DART_VERSION 2.7.2-1 -RUN apt-get install -y --no-install-recommends \ - `# Dart dependencies` \ - dart=$DART_VERSION -ENV PATH /usr/lib/dart/bin:$PATH - -RUN apt-get install -y --no-install-recommends \ - `# dotnet core dependencies` \ - dotnet-sdk-8.0 \ - dotnet-runtime-8.0 \ - aspnetcore-runtime-8.0 \ - dotnet-apphost-pack-8.0 - -# Erlang dependencies -ARG ERLANG_OTP_VERSION=20.3.8.9 -ARG ERLANG_REBAR_VERSION=3.13.2 -RUN apt-get update && apt-get install -y --no-install-recommends automake libncurses5-dev && \ - curl https://raw.githubusercontent.com/kerl/kerl/master/kerl -o /usr/local/bin/kerl && chmod +x /usr/local/bin/kerl && \ - kerl build $ERLANG_OTP_VERSION && kerl install $ERLANG_OTP_VERSION /usr/local/lib/otp/ && . /usr/local/lib/otp/activate && \ - curl https://s3.amazonaws.com/rebar3/rebar3 -o /usr/local/bin/rebar3 && chmod +x /usr/local/bin/rebar3 && \ - curl -ssLo /usr/local/bin/rebar3 https://github.com/erlang/rebar3/releases/download/${ERLANG_REBAR_VERSION}/rebar3 && chmod +x /usr/local/bin/rebar3 && \ - rebar3 --version -ENV PATH /usr/local/lib/otp/bin:$PATH - -RUN apt-get install -y --no-install-recommends \ - `# GlibC dependencies` \ - libglib2.0-dev - -# golang -ENV GOLANG_VERSION 1.18.5 -ENV GOLANG_DOWNLOAD_URL https://go.dev/dl/go$GOLANG_VERSION.linux-amd64.tar.gz -ENV GOLANG_DOWNLOAD_SHA256 9e5de37f9c49942c601b191ac5fba404b868bfc21d446d6960acc12283d6e5f2 -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 && \ - ln -s /usr/local/go/bin/go /usr/local/bin && \ - rm golang.tar.gz - -RUN apt-get install -y --no-install-recommends \ - `# Haxe dependencies` \ - haxe \ - neko \ - neko-dev \ - libneko0 && \ - haxelib setup --always /usr/share/haxe/lib && \ - haxelib install --always hxcpp 3.4.64 2>&1 > /dev/null -# note: hxcpp 3.4.185 (latest) no longer ships static libraries, and caused a build failure - -ENV GRADLE_VERSION="8.4" -RUN apt-get install -y --no-install-recommends \ - `# Java dependencies` \ - ant \ - ant-optional \ - openjdk-8-jdk \ - maven \ - unzip && \ - `# Gradle` \ - wget https://services.gradle.org/distributions/gradle-$GRADLE_VERSION-bin.zip -q -O /tmp/gradle-$GRADLE_VERSION-bin.zip && \ - (echo "3e1af3ae886920c3ac87f7a91f816c0c7c436f276a6eefdb3da152100fef72ae /tmp/gradle-$GRADLE_VERSION-bin.zip" | sha256sum -c -) && \ - unzip -d /tmp /tmp/gradle-$GRADLE_VERSION-bin.zip && \ - mv /tmp/gradle-$GRADLE_VERSION /usr/local/gradle && \ - ln -s /usr/local/gradle/bin/gradle /usr/local/bin - -# disabled: same as ubuntu-bionic jobs -# RUN apt-get install -y --no-install-recommends \ -# `# Lua dependencies` \ -# lua5.2 \ -# lua5.2-dev -# https://bugs.launchpad.net/ubuntu/+source/lua5.3/+bug/1707212 -# lua5.3 does not install alternatives so stick with 5.2 here - -RUN apt-get install -y --no-install-recommends \ - `# Node.js dependencies` \ - nodejs - -# Test dependencies for running puppeteer -RUN apt-get install -y --no-install-recommends \ - `# JS dependencies` \ - libxss1 \ - libxtst6 \ - libatk-bridge2.0-0 \ - libgtk-3-0 - -# THRIFT-4517: causes stack overflows; version too old; skip ocaml in xenial -# RUN apt-get install -y --no-install-recommends \ -# `# OCaml dependencies` \ -# ocaml \ -# opam && \ -# opam init --yes && \ -# opam install --yes oasis - -RUN apt-get install -y --no-install-recommends \ - `# Perl dependencies` \ - libbit-vector-perl \ - libclass-accessor-class-perl \ - libcrypt-ssleay-perl \ - libio-socket-ssl-perl \ - libnet-ssleay-perl \ - libtest-exception-perl - -RUN apt-get install -y --no-install-recommends \ - `# Php dependencies` \ - php7.0 \ - php7.0-cli \ - php7.0-dev \ - php-json \ - php-pear \ - re2c \ - composer - -RUN apt-get install -y --no-install-recommends \ - `# Python dependencies` \ - python-all \ - python-all-dbg \ - python-all-dev \ - python-backports.ssl-match-hostname \ - python-ipaddress \ - python-pip \ - python-setuptools \ - python-six \ - python-tornado \ - python-twisted \ - python-wheel \ - python-zope.interface \ - python3-all \ - python3-all-dbg \ - python3-all-dev \ - python3-setuptools \ - python3-six \ - python3-tornado \ - python3-twisted \ - python3-wheel \ - python3-zope.interface && \ - pip install --upgrade backports.ssl_match_hostname - -RUN apt-get install -y --no-install-recommends \ - `# Ruby dependencies` \ - ruby2.4 \ - ruby2.4-dev \ - ruby-bundler - -# Rust dependencies -RUN curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain 1.65.0 -y - -# Locale(s) for cpp unit tests -RUN apt-get install -y --no-install-recommends \ - `# Locale dependencies` \ - locales && \ - locale-gen en_US.UTF-8 && \ - locale-gen de_DE.UTF-8 && \ - update-locale - -# NOTE: this does not reduce the image size but adds an additional layer. -# # Clean up -# RUN rm -rf /var/cache/apt/* && \ -# rm -rf /var/lib/apt/lists/* && \ -# rm -rf /tmp/* && \ -# rm -rf /var/tmp/* - -ENV DOTNET_CLI_TELEMETRY_OPTOUT 1 -ENV THRIFT_ROOT /thrift -RUN mkdir -p $THRIFT_ROOT/src -COPY Dockerfile $THRIFT_ROOT/ -WORKDIR $THRIFT_ROOT/src diff --git a/build/docker/ubuntu-bionic/Dockerfile b/build/docker/ubuntu-bionic/Dockerfile deleted file mode 100644 index 350921ae50a..00000000000 --- a/build/docker/ubuntu-bionic/Dockerfile +++ /dev/null @@ -1,299 +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. - -# -# Apache Thrift Docker build environment for Ubuntu Bionic -# with some updated packages. -# - -FROM buildpack-deps:bionic-scm -LABEL MAINTAINER='Apache Thrift ' -ENV DEBIAN_FRONTEND noninteractive - -### Add apt repos - -RUN apt-get update -yq && \ - apt-get dist-upgrade -y && \ - apt-get install -y --no-install-recommends --fix-missing \ - apt \ - apt-transport-https \ - apt-utils \ - curl \ - dirmngr \ - software-properties-common \ - wget - -# Dart -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 - -# dotnet (netcore) -RUN curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > /etc/apt/trusted.gpg.d/microsoft.gpg && \ - wget -q -O /etc/apt/sources.list.d/microsoft-prod.list https://packages.microsoft.com/config/ubuntu/18.04/prod.list && \ - chown root:root /etc/apt/trusted.gpg.d/microsoft.gpg && \ - chown root:root /etc/apt/sources.list.d/microsoft-prod.list - -# node.js -RUN curl -sL https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add - && \ - echo "deb https://deb.nodesource.com/node_10.x bionic main" | tee /etc/apt/sources.list.d/nodesource.list - -### install general dependencies -RUN apt-get update && apt-get install -y --no-install-recommends \ - `# General dependencies` \ - bash-completion \ - bison \ - build-essential \ - clang \ - cmake \ - debhelper \ - flex \ - gdb \ - libasound2 \ - libatk-bridge2.0-0 \ - libgtk-3-0 \ - llvm \ - ninja-build \ - pkg-config \ - unzip \ - valgrind \ - vim -ENV PATH /usr/lib/llvm-6.0/bin:$PATH - -# lib/as3 (ActionScript) -RUN mkdir -p /usr/local/adobe/flex/4.6 && \ - cd /usr/local/adobe/flex/4.6 && \ - wget -q "http://download.macromedia.com/pub/flex/sdk/flex_sdk_4.6.zip" && \ - unzip flex_sdk_4.6.zip -ENV FLEX_HOME /usr/local/adobe/flex/4.6 - -# TODO: "apt-get install" without "apt-get update" in the same "RUN" step can cause cache issues if modified later. -# See https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#run -RUN apt-get install -y --no-install-recommends \ - `# C++ dependencies` \ - libboost-all-dev \ - libevent-dev \ - libssl-dev \ - qt5-default \ - qtbase5-dev \ - qtbase5-dev-tools - -ENV SBCL_VERSION 1.5.3 -RUN \ - `# Common Lisp (sbcl) dependencies` \ - curl --version && \ - 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 && \ - sbcl --version && \ - cd .. && \ - rm -rf sbcl* - -ENV D_VERSION 2.087.0 -ENV DMD_DEB dmd_2.087.0-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 && \ - 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.7.2-1 -RUN apt-get install -y --no-install-recommends \ - `# Dart dependencies` \ - dart=$DART_VERSION -ENV PATH /usr/lib/dart/bin:$PATH - -RUN apt-get install -y --no-install-recommends \ - `# dotnet core dependencies` \ - dotnet-sdk-8.0 \ - dotnet-runtime-8.0 \ - aspnetcore-runtime-8.0 \ - dotnet-apphost-pack-8.0 - -# Erlang dependencies -ARG ERLANG_OTP_VERSION=23.3.4.11 -ARG ERLANG_REBAR_VERSION=3.18.0 -RUN apt-get update && apt-get install -y --no-install-recommends libncurses5-dev && \ - curl -ssLo /usr/local/bin/kerl https://raw.githubusercontent.com/kerl/kerl/master/kerl && chmod +x /usr/local/bin/kerl && \ - kerl build $ERLANG_OTP_VERSION && kerl install $ERLANG_OTP_VERSION /usr/local/lib/otp/ && . /usr/local/lib/otp/activate && \ - curl -ssLo /usr/local/bin/rebar3 https://github.com/erlang/rebar3/releases/download/${ERLANG_REBAR_VERSION}/rebar3 && chmod +x /usr/local/bin/rebar3 && \ - rebar3 --version -ENV PATH /usr/local/lib/otp/bin:$PATH - -RUN apt-get install -y --no-install-recommends \ - `# GlibC dependencies` \ - libglib2.0-dev - -# golang -ENV GOLANG_VERSION 1.19.5 -ENV GOLANG_DOWNLOAD_URL https://go.dev/dl/go$GOLANG_VERSION.linux-amd64.tar.gz -ENV GOLANG_DOWNLOAD_SHA256 36519702ae2fd573c9869461990ae550c8c0d955cd28d2827a6b159fda81ff95 -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 && \ - ln -s /usr/local/go/bin/go /usr/local/bin && \ - rm golang.tar.gz - -RUN apt-get install -y --no-install-recommends \ - `# Haxe dependencies` \ - haxe \ - neko \ - neko-dev && \ - haxelib setup --always /usr/share/haxe/lib && \ - haxelib install --always hxcpp 2>&1 > /dev/null - -ENV GRADLE_VERSION="8.4" -RUN apt-get install -y --no-install-recommends \ - `# Java dependencies` \ - ant \ - ant-optional \ - maven \ - openjdk-17-jdk-headless && \ - `# Gradle` \ - wget https://services.gradle.org/distributions/gradle-$GRADLE_VERSION-bin.zip -q -O /tmp/gradle-$GRADLE_VERSION-bin.zip && \ - (echo "3e1af3ae886920c3ac87f7a91f816c0c7c436f276a6eefdb3da152100fef72ae /tmp/gradle-$GRADLE_VERSION-bin.zip" | sha256sum -c -) && \ - unzip -d /tmp /tmp/gradle-$GRADLE_VERSION-bin.zip && \ - mv /tmp/gradle-$GRADLE_VERSION /usr/local/gradle && \ - ln -s /usr/local/gradle/bin/gradle /usr/local/bin - -RUN apt-get install -y --no-install-recommends \ - `# Lua dependencies` \ - lua5.2 \ - lua5.2-dev -# https://bugs.launchpad.net/ubuntu/+source/lua5.3/+bug/1707212 -# lua5.3 does not install alternatives! -# need to update our luasocket code, lua doesn't have luaL_openlib any more - -RUN apt-get install -y --no-install-recommends \ - `# Node.js dependencies` \ - nodejs - -# Test dependencies for running puppeteer -RUN apt-get install -y --no-install-recommends \ - `# JS dependencies` \ - libxss1 \ - libxtst6 - -RUN apt-get install -y --no-install-recommends \ - `# OCaml dependencies` \ - ocaml \ - opam && \ - opam init --yes && \ - opam install --yes oasis - -RUN apt-get install -y --no-install-recommends \ - `# Perl dependencies` \ - libbit-vector-perl \ - libclass-accessor-class-perl \ - libcrypt-ssleay-perl \ - libio-socket-ssl-perl \ - libnet-ssleay-perl \ - libtest-exception-perl - -RUN apt-get install -y --no-install-recommends \ - `# Php dependencies` \ - php \ - php-cli \ - php-dev \ - php-json \ - php-pear \ - re2c \ - composer - -RUN apt-get install -y --no-install-recommends \ - `# Python dependencies` \ - python-all \ - python-all-dbg \ - python-all-dev \ - python-ipaddress \ - python-pip \ - python-setuptools \ - python-six \ - python-tornado \ - python-twisted \ - python-wheel \ - python-zope.interface && \ - pip install --upgrade backports.ssl_match_hostname - -RUN apt-get install -y --no-install-recommends \ - `# Python3 dependencies` \ - python3-all \ - python3-all-dbg \ - python3-all-dev \ - python3-pip \ - python3-setuptools \ - python3-six \ - python3-tornado \ - python3-twisted \ - python3-wheel \ - python3-zope.interface - -RUN apt-get install -y --no-install-recommends \ - `# Ruby dependencies` \ - ruby \ - ruby-dev \ - ruby-bundler - -# Rust dependencies -RUN curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain 1.65.0 -y -ENV PATH /root/.cargo/bin:$PATH - -# Swift on Linux for cross tests -RUN apt-get install -yq \ - libedit-dev \ - libz3-dev \ - libpython-dev \ - libxml2-dev && \ - cd / && \ - wget --quiet https://download.swift.org/swift-5.7-release/ubuntu1804/swift-5.7-RELEASE/swift-5.7-RELEASE-ubuntu18.04.tar.gz && \ - tar xf swift-5.7-RELEASE-ubuntu18.04.tar.gz && \ - mv swift-5.7-RELEASE-ubuntu18.04 /usr/share/swift && \ - rm swift-5.7-RELEASE-ubuntu18.04.tar.gz - -ENV PATH /usr/share/swift/usr/bin:$PATH -RUN swift --version - -# Locale(s) for cpp unit tests -RUN apt-get install -y --no-install-recommends \ - `# Locale dependencies` \ - locales && \ - locale-gen en_US.UTF-8 && \ - locale-gen de_DE.UTF-8 && \ - update-locale - -RUN apt-get install -y --no-install-recommends \ - `# Static Code Analysis dependencies` \ - cppcheck \ - sloccount && \ - pip install flake8 - -# NOTE: this does not reduce the image size but adds an additional layer. -# # Clean up -# RUN rm -rf /var/cache/apt/* && \ -# rm -rf /var/lib/apt/lists/* && \ -# rm -rf /tmp/* && \ -# rm -rf /var/tmp/* - -ENV THRIFT_ROOT /thrift -RUN mkdir -p $THRIFT_ROOT/src -COPY Dockerfile $THRIFT_ROOT/ -WORKDIR $THRIFT_ROOT/src diff --git a/build/docker/ubuntu-focal/Dockerfile b/build/docker/ubuntu-focal/Dockerfile index 416e806469c..e0244fcd6d1 100644 --- a/build/docker/ubuntu-focal/Dockerfile +++ b/build/docker/ubuntu-focal/Dockerfile @@ -32,6 +32,20 @@ RUN apt-get update -yq && \ software-properties-common \ wget +# Create a user +ARG user=build +ARG group=build +ARG uid=1000 +ARG gid=1000 + +RUN apt-get install -y --no-install-recommends sudo && \ + echo "Running with: UID: ${uid}, User: ${user}, GID: ${gid}, Group: ${group}" && \ + if [ -z `cat /etc/group | grep "${group}:"` ] && [ -z `cat /etc/group | grep ":${gid}:"` ]; then addgroup --gid ${gid} ${group}; fi && \ + if [ -z `cat /etc/passwd | grep "${user}:"` ] && [ -z `cat /etc/passwd | grep ":${uid}:"` ]; then adduser --uid ${uid} --gid ${gid} --shell /bin/bash ${user} --disabled-password -q --gecos ""; fi && \ + echo "${user} ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers && \ + mkdir -p /home/${user} && \ + chown -R ${user}:${group} /home/${user} + # Dart 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 > \ @@ -39,7 +53,7 @@ RUN curl https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - & # dotnet (netcore) RUN curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > /etc/apt/trusted.gpg.d/microsoft.gpg && \ - wget -q -O /etc/apt/sources.list.d/microsoft-prod.list https://packages.microsoft.com/config/ubuntu/18.04/prod.list && \ + wget -q -O /etc/apt/sources.list.d/microsoft-prod.list https://packages.microsoft.com/config/ubuntu/20.04/prod.list && \ chown root:root /etc/apt/trusted.gpg.d/microsoft.gpg && \ chown root:root /etc/apt/sources.list.d/microsoft-prod.list @@ -123,6 +137,7 @@ RUN apt-get install -y --no-install-recommends \ dart=$DART_VERSION ENV PATH /usr/lib/dart/bin:$PATH +# Because Ubuntu 20.04 reaches end of life in April [actually May] 2025, Microsoft has decided not to support .NET 9 on Ubuntu 20.04. RUN apt-get install -y --no-install-recommends \ `# dotnet core dependencies` \ dotnet-sdk-8.0 \ @@ -145,22 +160,37 @@ RUN apt-get install -y --no-install-recommends \ libglib2.0-dev # golang -ENV GOLANG_VERSION 1.20 +ENV GOLANG_VERSION 1.24.3 ENV GOLANG_DOWNLOAD_URL https://go.dev/dl/go$GOLANG_VERSION.linux-amd64.tar.gz -ENV GOLANG_DOWNLOAD_SHA256 5a9ebcc65c1cce56e0d2dc616aff4c4cedcfbda8cc6f0288cc08cda3b18dcbf1 +ENV GOLANG_DOWNLOAD_SHA256 3333f6ea53afa971e9078895eaa4ac7204a8c6b5c68c10e6bc9a33e8e391bdd8 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 && \ ln -s /usr/local/go/bin/go /usr/local/bin && \ rm golang.tar.gz -RUN apt-get install -y --no-install-recommends \ - `# Haxe dependencies` \ - haxe \ - neko \ - neko-dev && \ - haxelib setup --always /usr/share/haxe/lib && \ - haxelib install --always hxcpp 2>&1 > /dev/null +# HAXE +ARG HAXE_VERSION=4.2.1 +ARG NEKO_VERSION=2.3.0 +RUN cd $HOME && \ + `# Haxe dependencies` && \ + wget https://github.com/HaxeFoundation/haxe/releases/download/${HAXE_VERSION}/haxe-${HAXE_VERSION}-linux64.tar.gz && \ + tar xvf haxe-${HAXE_VERSION}-linux64.tar.gz && \ + rm haxe-${HAXE_VERSION}-linux64.tar.gz && \ + mv haxe_* /opt/haxe && \ + wget https://github.com/HaxeFoundation/neko/releases/download/v`echo ${NEKO_VERSION} | sed "s/\./-/g"`/neko-${NEKO_VERSION}-linux64.tar.gz && \ + tar xvf neko-${NEKO_VERSION}-linux64.tar.gz && \ + rm neko-${NEKO_VERSION}-linux64.tar.gz && \ + mv neko-* /opt/neko +ENV PATH /opt/haxe:/opt/neko:$PATH +RUN echo "/opt/neko" > /etc/ld.so.conf.d/neko.conf && \ + ldconfig +USER ${user} +RUN mkdir -p $HOME/haxe/lib && \ + haxelib setup --always $HOME/haxe/lib && \ + haxelib install --always hxcpp 2>&1 > /dev/null && \ + haxelib install --always uuid 2>&1 > /dev/null +USER root ENV GRADLE_VERSION="8.4" RUN apt-get install -y --no-install-recommends \ @@ -213,10 +243,13 @@ RUN apt-get install -y --no-install-recommends \ RUN apt-get install -y --no-install-recommends \ `# Php dependencies` \ - php \ - php-cli \ - php-dev \ - php-json \ + php7.4 \ + php7.4-cli \ + php7.4-dev \ + php7.4-mbstring \ + php7.4-xml \ + php7.4-curl \ + php7.4-xdebug \ php-pear \ re2c \ composer @@ -228,7 +261,6 @@ RUN apt-get install -y --no-install-recommends \ python3-all-dev \ python3-pip \ python3-setuptools \ - python3-six \ python3-tornado \ python3-twisted \ python3-wheel \ @@ -240,9 +272,11 @@ RUN apt-get install -y --no-install-recommends \ ruby-dev \ ruby-bundler -# Rust dependencies -RUN curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain 1.65.0 -y -ENV PATH /root/.cargo/bin:$PATH +USER ${user} +RUN `# Rust dependencies` \ + curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain 1.83.0 -y +ENV PATH /home/${user}/.cargo/bin:$PATH +USER root # Swift on Linux for cross tests RUN apt-get install -yq \ @@ -281,6 +315,9 @@ RUN apt-get install -y --no-install-recommends \ # rm -rf /var/tmp/* ENV THRIFT_ROOT /thrift -RUN mkdir -p $THRIFT_ROOT/src +RUN mkdir -p $THRIFT_ROOT/src && \ + chown -R ${uid}:${uid} $THRIFT_ROOT/ COPY Dockerfile $THRIFT_ROOT/ WORKDIR $THRIFT_ROOT/src + +USER ${user} diff --git a/build/docker/ubuntu-jammy/Dockerfile b/build/docker/ubuntu-jammy/Dockerfile index a10fea6500a..8f66a5646e7 100644 --- a/build/docker/ubuntu-jammy/Dockerfile +++ b/build/docker/ubuntu-jammy/Dockerfile @@ -32,17 +32,25 @@ RUN apt-get update -yq && \ software-properties-common \ wget +# Create a user +ARG user=build +ARG group=build +ARG uid=1000 +ARG gid=1000 + +RUN apt-get install -y --no-install-recommends sudo && \ + echo "Running with: UID: ${uid}, User: ${user}, GID: ${gid}, Group: ${group}" && \ + if [ -z `cat /etc/group | grep "${group}:"` ] && [ -z `cat /etc/group | grep ":${gid}:"` ]; then addgroup --gid ${gid} ${group}; fi && \ + if [ -z `cat /etc/passwd | grep "${user}:"` ] && [ -z `cat /etc/passwd | grep ":${uid}:"` ]; then adduser --uid ${uid} --gid ${gid} --shell /bin/bash ${user} --disabled-password -q --gecos ""; fi && \ + echo "${user} ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers && \ + mkdir -p /home/${user} && \ + chown -R ${user}:${group} /home/${user} + # Dart 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 -# dotnet (netcore) -RUN curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > /etc/apt/trusted.gpg.d/microsoft.gpg && \ - wget -q -O /etc/apt/sources.list.d/microsoft-prod.list https://packages.microsoft.com/config/ubuntu/18.04/prod.list && \ - chown root:root /etc/apt/trusted.gpg.d/microsoft.gpg && \ - chown root:root /etc/apt/sources.list.d/microsoft-prod.list - # node.js RUN curl -sL https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add - && \ echo "deb https://deb.nodesource.com/node_16.x focal main" | tee /etc/apt/sources.list.d/nodesource.list @@ -84,7 +92,6 @@ RUN apt-get install -y --no-install-recommends \ libboost-all-dev \ libevent-dev \ libssl-dev \ - qt5-default \ qtbase5-dev \ qtbase5-dev-tools @@ -123,15 +130,16 @@ RUN apt-get install -y --no-install-recommends \ dart=$DART_VERSION ENV PATH /usr/lib/dart/bin:$PATH +RUN add-apt-repository ppa:dotnet/backports RUN apt-get install -y --no-install-recommends \ `# dotnet core dependencies` \ - dotnet-sdk-8.0 \ - dotnet-runtime-8.0 \ - aspnetcore-runtime-8.0 \ - dotnet-apphost-pack-8.0 + dotnet-sdk-9.0 \ + dotnet-runtime-9.0 \ + aspnetcore-runtime-9.0 \ + dotnet-apphost-pack-9.0 # Erlang dependencies -ARG ERLANG_OTP_VERSION=23.3.4.11 +ARG ERLANG_OTP_VERSION=25.3.2.9 ARG ERLANG_REBAR_VERSION=3.18.0 RUN apt-get update && apt-get install -y --no-install-recommends libncurses5-dev && \ curl -ssLo /usr/local/bin/kerl https://raw.githubusercontent.com/kerl/kerl/master/kerl && chmod +x /usr/local/bin/kerl && \ @@ -145,22 +153,37 @@ RUN apt-get install -y --no-install-recommends \ libglib2.0-dev # golang -ENV GOLANG_VERSION 1.20 +ENV GOLANG_VERSION 1.24.3 ENV GOLANG_DOWNLOAD_URL https://go.dev/dl/go$GOLANG_VERSION.linux-amd64.tar.gz -ENV GOLANG_DOWNLOAD_SHA256 5a9ebcc65c1cce56e0d2dc616aff4c4cedcfbda8cc6f0288cc08cda3b18dcbf1 +ENV GOLANG_DOWNLOAD_SHA256 3333f6ea53afa971e9078895eaa4ac7204a8c6b5c68c10e6bc9a33e8e391bdd8 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 && \ ln -s /usr/local/go/bin/go /usr/local/bin && \ rm golang.tar.gz -RUN apt-get install -y --no-install-recommends \ - `# Haxe dependencies` \ - haxe \ - neko \ - neko-dev && \ - haxelib setup --always /usr/share/haxe/lib && \ - haxelib install --always hxcpp 2>&1 > /dev/null +# HAXE +ARG HAXE_VERSION=4.2.1 +ARG NEKO_VERSION=2.3.0 +RUN cd $HOME && \ + `# Haxe dependencies` && \ + wget https://github.com/HaxeFoundation/haxe/releases/download/${HAXE_VERSION}/haxe-${HAXE_VERSION}-linux64.tar.gz && \ + tar xvf haxe-${HAXE_VERSION}-linux64.tar.gz && \ + rm haxe-${HAXE_VERSION}-linux64.tar.gz && \ + mv haxe_* /opt/haxe && \ + wget https://github.com/HaxeFoundation/neko/releases/download/v`echo ${NEKO_VERSION} | sed "s/\./-/g"`/neko-${NEKO_VERSION}-linux64.tar.gz && \ + tar xvf neko-${NEKO_VERSION}-linux64.tar.gz && \ + rm neko-${NEKO_VERSION}-linux64.tar.gz && \ + mv neko-* /opt/neko +ENV PATH /opt/haxe:/opt/neko:$PATH +RUN echo "/opt/neko" > /etc/ld.so.conf.d/neko.conf && \ + ldconfig +USER ${user} +RUN mkdir -p $HOME/haxe/lib && \ + haxelib setup --always $HOME/haxe/lib && \ + haxelib install --always hxcpp 2>&1 > /dev/null && \ + haxelib install --always uuid 2>&1 > /dev/null +USER root ENV GRADLE_VERSION="8.4" RUN apt-get install -y --no-install-recommends \ @@ -168,7 +191,7 @@ RUN apt-get install -y --no-install-recommends \ ant \ ant-optional \ maven \ - openjdk-11-jdk-headless && \ + openjdk-17-jdk-headless && \ `# Gradle` \ wget https://services.gradle.org/distributions/gradle-$GRADLE_VERSION-bin.zip -q -O /tmp/gradle-$GRADLE_VERSION-bin.zip && \ (echo "3e1af3ae886920c3ac87f7a91f816c0c7c436f276a6eefdb3da152100fef72ae /tmp/gradle-$GRADLE_VERSION-bin.zip" | sha256sum -c -) && \ @@ -178,8 +201,8 @@ RUN apt-get install -y --no-install-recommends \ RUN apt-get install -y --no-install-recommends \ `# Lua dependencies` \ - lua5.2 \ - lua5.2-dev + lua5.4 \ + liblua5.4-dev # https://bugs.launchpad.net/ubuntu/+source/lua5.3/+bug/1707212 # lua5.3 does not install alternatives! # need to update our luasocket code, lua doesn't have luaL_openlib any more @@ -213,10 +236,13 @@ RUN apt-get install -y --no-install-recommends \ RUN apt-get install -y --no-install-recommends \ `# Php dependencies` \ - php \ - php-cli \ - php-dev \ - php-json \ + php8.1 \ + php8.1-cli \ + php8.1-dev \ + php8.1-mbstring \ + php8.1-xml \ + php8.1-curl \ + php8.1-xdebug \ php-pear \ re2c \ composer @@ -228,7 +254,6 @@ RUN apt-get install -y --no-install-recommends \ python3-all-dev \ python3-pip \ python3-setuptools \ - python3-six \ python3-tornado \ python3-twisted \ python3-wheel \ @@ -240,9 +265,11 @@ RUN apt-get install -y --no-install-recommends \ ruby-dev \ ruby-bundler -# Rust dependencies -RUN curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain 1.65.0 -y -ENV PATH /root/.cargo/bin:$PATH +USER ${user} +RUN `# Rust dependencies` \ + curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain 1.83.0 -y +ENV PATH /home/${user}/.cargo/bin:$PATH +USER root # Swift on Linux for cross tests RUN apt-get install -yq \ @@ -281,6 +308,9 @@ RUN apt-get install -y --no-install-recommends \ # rm -rf /var/tmp/* ENV THRIFT_ROOT /thrift -RUN mkdir -p $THRIFT_ROOT/src +RUN mkdir -p $THRIFT_ROOT/src && \ + chown -R ${uid}:${uid} $THRIFT_ROOT/ COPY Dockerfile $THRIFT_ROOT/ WORKDIR $THRIFT_ROOT/src + +USER ${user} diff --git a/build/veralign.sh b/build/veralign.sh index 834bf7e03d3..b929f1f49e9 100755 --- a/build/veralign.sh +++ b/build/veralign.sh @@ -68,11 +68,15 @@ FILES[lib/java/gradle.properties]=simpleReplace FILES[lib/js/package-lock.json]=jsonReplace FILES[lib/js/package.json]=jsonReplace FILES[lib/js/src/thrift.js]=simpleReplace +FILES[lib/js/package-lock.json]=simpleReplace FILES[lib/lua/Thrift.lua]=simpleReplace -FILES[lib/netstd/Tests/Thrift.Tests/Thrift.Tests.csproj]=simpleReplace -FILES[lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift.PublicInterfaces.Compile.Tests.csproj]=simpleReplace -FILES[lib/netstd/Tests/Thrift.IntegrationTests/Thrift.IntegrationTests.csproj]=simpleReplace FILES[lib/netstd/Thrift/Properties/AssemblyInfo.cs]=simpleReplace +FILES[lib/netstd/Benchmarks/Thrift.Benchmarks/Thrift.Benchmarks.csproj]=simpleReplace +FILES[lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.net8/Thrift.Compile.net8.csproj]=simpleReplace +FILES[lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.net9/Thrift.Compile.net9.csproj]=simpleReplace +FILES[lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.netstd2/Thrift.Compile.netstd2.csproj]=simpleReplace +FILES[lib/netstd/Tests/Thrift.IntegrationTests/Thrift.IntegrationTests.csproj]=simpleReplace +FILES[lib/netstd/Tests/Thrift.Tests/Thrift.Tests.csproj]=simpleReplace FILES[lib/netstd/Thrift/Thrift.csproj]=simpleReplace FILES[lib/ocaml/_oasis]=simpleReplace FILES[lib/perl/lib/Thrift.pm]=simpleReplace @@ -101,6 +105,8 @@ FILES[tutorial/netstd/Client/Client.csproj]=simpleReplace FILES[tutorial/netstd/Interfaces/Interfaces.csproj]=simpleReplace FILES[tutorial/netstd/Server/Server.csproj]=simpleReplace FILES[tutorial/ocaml/_oasis]=simpleReplace +FILES[lib/ts/package-lock.json]=simpleReplace +FILES[package-lock.json]=simpleReplace diff --git a/compiler/cpp/CMakeLists.txt b/compiler/cpp/CMakeLists.txt index 013d3d3c985..db5fcb07f61 100644 --- a/compiler/cpp/CMakeLists.txt +++ b/compiler/cpp/CMakeLists.txt @@ -17,7 +17,7 @@ # under the License. # -cmake_minimum_required(VERSION 3.3) +cmake_minimum_required(VERSION 3.16) project("thrift-compiler" VERSION ${PACKAGE_VERSION}) # version.h now handled via veralign.sh diff --git a/compiler/cpp/Makefile.am b/compiler/cpp/Makefile.am index 677a39dafe5..41cb76e8e1b 100644 --- a/compiler/cpp/Makefile.am +++ b/compiler/cpp/Makefile.am @@ -115,6 +115,9 @@ WINDOWS_DIST = \ compiler.vcxproj \ compiler.vcxproj.filters +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ coding_standards.md \ README.md \ diff --git a/compiler/cpp/compiler.vcxproj b/compiler/cpp/compiler.vcxproj index 9fbf903a43a..9cc2ccbb786 100644 --- a/compiler/cpp/compiler.vcxproj +++ b/compiler/cpp/compiler.vcxproj @@ -83,6 +83,8 @@ + + @@ -103,23 +105,27 @@ Application true MultiByte + v143 Application true MultiByte + v143 Application false true MultiByte + v143 Application false true MultiByte + v143 @@ -248,4 +254,4 @@ - + \ No newline at end of file diff --git a/compiler/cpp/src/Makefile.am b/compiler/cpp/src/Makefile.am index 5111fd55038..5b6802a4d84 100644 --- a/compiler/cpp/src/Makefile.am +++ b/compiler/cpp/src/Makefile.am @@ -39,6 +39,9 @@ clean-local: $(RM) thrift/thriftl.cc thrift/thrifty.cc thrift/thrifty.h thrift/thrifty.hh +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ thrift/logging.cc \ thrift/windows/config.h diff --git a/compiler/cpp/src/thrift/generate/go_validator_generator.cc b/compiler/cpp/src/thrift/generate/go_validator_generator.cc index 1f5a3ad6eca..0adff2ee984 100644 --- a/compiler/cpp/src/thrift/generate/go_validator_generator.cc +++ b/compiler/cpp/src/thrift/generate/go_validator_generator.cc @@ -82,19 +82,19 @@ void go_validator_generator::generate_field_validator(std::ostream& out, } if (type->is_enum()) { if (context.tgt[0] == '*') { - out << indent() << "if " << context.tgt.substr(1) << " != nil {" << endl; + out << indent() << "if " << context.tgt.substr(1) << " != nil {" << '\n'; indent_up(); } generate_enum_field_validator(out, context); if (context.tgt[0] == '*') { indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } return; } else if (type->is_base_type()) { t_base_type::t_base tbase = ((t_base_type*)type)->get_base(); if (context.tgt[0] == '*') { - out << indent() << "if " << context.tgt.substr(1) << " != nil {" << endl; + out << indent() << "if " << context.tgt.substr(1) << " != nil {" << '\n'; indent_up(); } switch (tbase) { @@ -119,7 +119,7 @@ void go_validator_generator::generate_field_validator(std::ostream& out, } if (context.tgt[0] == '*') { indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } return; } else if (type->is_list()) { @@ -146,7 +146,7 @@ void go_validator_generator::generate_enum_field_validator(std::ostream& out, if (key == "vt.in") { if (values.size() > 1) { std::string exist = GenID("_exist"); - out << indent() << "var " << exist << " bool" << endl; + out << indent() << "var " << exist << " bool" << '\n'; std::string src = GenID("_src"); out << indent() << src << " := []int64{"; @@ -162,19 +162,19 @@ void go_validator_generator::generate_enum_field_validator(std::ostream& out, } out << ")"; } - out << "}" << endl; + out << "}" << '\n'; - out << indent() << "for _, src := range " << src << " {" << endl; + out << indent() << "for _, src := range " << src << " {" << '\n'; indent_up(); - out << indent() << "if int64(" << context.tgt << ") == src {" << endl; + out << indent() << "if int64(" << context.tgt << ") == src {" << '\n'; indent_up(); - out << indent() << exist << " = true" << endl; - out << indent() << "break" << endl; + out << indent() << exist << " = true" << '\n'; + out << indent() << "break" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; indent_down(); - out << indent() << "}" << endl; - out << indent() << "if " << exist << " == false {" << endl; + out << indent() << "}" << '\n'; + out << indent() << "if " << exist << " == false {" << '\n'; } else { out << indent() << "if int64(" << context.tgt << ") != int64("; if (values[0]->is_field_reference()) { @@ -182,18 +182,18 @@ void go_validator_generator::generate_enum_field_validator(std::ostream& out, } else { out << values[0]->get_enum()->get_value(); } - out << ") {" << endl; + out << ") {" << '\n'; } indent_up(); out << indent() << "return thrift.NewValidationException(thrift.VALIDATION_FAILED, \"vt.in\", \"" << context.field_symbol << "\", \"" << context.field_symbol - << " not valid, rule vt.in check failed\")" << endl; + << " not valid, rule vt.in check failed\")" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; if (values.size() > 1) { indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } } else if (key == "vt.not_in") { if (values.size() > 1) { @@ -211,11 +211,11 @@ void go_validator_generator::generate_enum_field_validator(std::ostream& out, } out << ")"; } - out << "}" << endl; + out << "}" << '\n'; - out << indent() << "for _, src := range " << src << " {" << endl; + out << indent() << "for _, src := range " << src << " {" << '\n'; indent_up(); - out << indent() << "if int64(" << context.tgt << ") == src {" << endl; + out << indent() << "if int64(" << context.tgt << ") == src {" << '\n'; } else { out << indent() << "if int64(" << context.tgt << ") == "; out << "int64("; @@ -224,18 +224,18 @@ void go_validator_generator::generate_enum_field_validator(std::ostream& out, } else { out << values[0]->get_enum()->get_value(); } - out << ") {" << endl; + out << ") {" << '\n'; } indent_up(); out << indent() << "return thrift.NewValidationException(thrift.VALIDATION_FAILED, \"vt.not_in\", \"" << context.field_symbol << "\", \"" << context.field_symbol - << " not valid, rule vt.not_in check failed\")" << endl; + << " not valid, rule vt.not_in check failed\")" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; if (values.size() > 1) { indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } } else if (key == "vt.defined_only") { if (values[0]->get_bool()) { @@ -243,14 +243,14 @@ void go_validator_generator::generate_enum_field_validator(std::ostream& out, } else { continue; } - out << "{" << endl; + out << "{" << '\n'; indent_up(); out << indent() << "return thrift.NewValidationException(thrift.VALIDATION_FAILED, \"" + key + "\", \"" << context.field_symbol << "\", \"" << context.field_symbol << " not valid, rule " << key - << " check failed\")" << endl; + << " check failed\")" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } } } @@ -276,14 +276,14 @@ void go_validator_generator::generate_bool_field_validator(std::ostream& out, } } } - out << "{" << endl; + out << "{" << '\n'; indent_up(); out << indent() << "return thrift.NewValidationException(thrift.VALIDATION_FAILED, \"" + key + "\", \"" << context.field_symbol << "\", \"" << context.field_symbol << " not valid, rule " << key - << " check failed\")" << endl; + << " check failed\")" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } } @@ -308,19 +308,19 @@ void go_validator_generator::generate_double_field_validator(std::ostream& out, } else { out << values[0]->get_double(); } - out << "{" << endl; + out << "{" << '\n'; indent_up(); out << indent() << "return thrift.NewValidationException(thrift.VALIDATION_FAILED, \"" + key + "\", \"" << context.field_symbol << "\", \"" << context.field_symbol << " not valid, rule " << key - << " check failed\")" << endl; + << " check failed\")" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; continue; } else if (key == "vt.in") { if (values.size() > 1) { std::string exist = GenID("_exist"); - out << indent() << "var " << exist << " bool" << endl; + out << indent() << "var " << exist << " bool" << '\n'; std::string src = GenID("_src"); out << indent() << src << " := []float64{"; @@ -334,19 +334,19 @@ void go_validator_generator::generate_double_field_validator(std::ostream& out, out << (*it)->get_double(); } } - out << "}" << endl; + out << "}" << '\n'; - out << indent() << "for _, src := range " << src << " {" << endl; + out << indent() << "for _, src := range " << src << " {" << '\n'; indent_up(); - out << indent() << "if " << context.tgt << " == src {" << endl; + out << indent() << "if " << context.tgt << " == src {" << '\n'; indent_up(); - out << indent() << exist << " = true" << endl; - out << indent() << "break" << endl; + out << indent() << exist << " = true" << '\n'; + out << indent() << "break" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; indent_down(); - out << indent() << "}" << endl; - out << indent() << "if " << exist << " == false {" << endl; + out << indent() << "}" << '\n'; + out << indent() << "if " << exist << " == false {" << '\n'; } else { out << indent() << "if " << context.tgt << " != "; if (values[0]->is_field_reference()) { @@ -354,16 +354,16 @@ void go_validator_generator::generate_double_field_validator(std::ostream& out, } else { out << values[0]->get_double(); } - out << "{" << endl; + out << "{" << '\n'; } indent_up(); out << indent() << "return thrift.NewValidationException(thrift.VALIDATION_FAILED, \"vt.in\", \"" << context.field_symbol << "\", \"" << context.field_symbol - << " not valid, rule vt.in check failed\")" << endl; + << " not valid, rule vt.in check failed\")" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } else if (key == "vt.not_in") { if (values.size() > 1) { std::string src = GenID("_src"); @@ -378,11 +378,11 @@ void go_validator_generator::generate_double_field_validator(std::ostream& out, out << (*it)->get_double(); } } - out << "}" << endl; + out << "}" << '\n'; - out << indent() << "for _, src := range " << src << " {" << endl; + out << indent() << "for _, src := range " << src << " {" << '\n'; indent_up(); - out << indent() << "if " << context.tgt << " == src {" << endl; + out << indent() << "if " << context.tgt << " == src {" << '\n'; } else { out << indent() << "if " << context.tgt << " == "; if (values[0]->is_field_reference()) { @@ -390,18 +390,18 @@ void go_validator_generator::generate_double_field_validator(std::ostream& out, } else { out << values[0]->get_double(); } - out << "{" << endl; + out << "{" << '\n'; } indent_up(); out << indent() << "return thrift.NewValidationException(thrift.VALIDATION_FAILED, \"vt.not_in\", \"" << context.field_symbol << "\", \"" << context.field_symbol - << " not valid, rule vt.not_in check failed\")" << endl; + << " not valid, rule vt.not_in check failed\")" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; if (values.size() > 1) { indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } } } @@ -460,18 +460,18 @@ void go_validator_generator::generate_integer_field_validator(std::ostream& out, } else { out << values[0]->get_int(); } - out << "{" << endl; + out << "{" << '\n'; indent_up(); out << indent() << "return thrift.NewValidationException(thrift.VALIDATION_FAILED, \"" + key + "\", \"" << context.field_symbol << "\", \"" << context.field_symbol << " not valid, rule " << key - << " check failed\")" << endl; + << " check failed\")" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } else if (key == "vt.in") { if (values.size() > 1) { std::string exist = GenID("_exist"); - out << indent() << "var " << exist << " bool" << endl; + out << indent() << "var " << exist << " bool" << '\n'; std::string src = GenID("_src"); out << indent() << src << " := []"; @@ -499,19 +499,19 @@ void go_validator_generator::generate_integer_field_validator(std::ostream& out, out << (*it)->get_int(); } } - out << "}" << endl; + out << "}" << '\n'; - out << indent() << "for _, src := range " << src << " {" << endl; + out << indent() << "for _, src := range " << src << " {" << '\n'; indent_up(); - out << indent() << "if " << context.tgt << " == src {" << endl; + out << indent() << "if " << context.tgt << " == src {" << '\n'; indent_up(); - out << indent() << exist << " = true" << endl; - out << indent() << "break" << endl; + out << indent() << exist << " = true" << '\n'; + out << indent() << "break" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; indent_down(); - out << indent() << "}" << endl; - out << indent() << "if " << exist << " == false {" << endl; + out << indent() << "}" << '\n'; + out << indent() << "if " << exist << " == false {" << '\n'; } else { out << indent() << "if " << context.tgt << " != "; if (values[0]->is_field_reference()) { @@ -531,15 +531,15 @@ void go_validator_generator::generate_integer_field_validator(std::ostream& out, } else { out << values[0]->get_int(); } - out << "{" << endl; + out << "{" << '\n'; } indent_up(); out << indent() << "return thrift.NewValidationException(thrift.VALIDATION_FAILED, \"vt.in\", \"" << context.field_symbol << "\", \"" << context.field_symbol - << " not valid, rule vt.in check failed\")" << endl; + << " not valid, rule vt.in check failed\")" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } else if (key == "vt.not_in") { if (values.size() > 1) { std::string src = GenID("_src"); @@ -584,11 +584,11 @@ void go_validator_generator::generate_integer_field_validator(std::ostream& out, out << (*it)->get_int(); } } - out << "}" << endl; + out << "}" << '\n'; - out << indent() << "for _, src := range " << src << " {" << endl; + out << indent() << "for _, src := range " << src << " {" << '\n'; indent_up(); - out << indent() << "if " << context.tgt << " == src {" << endl; + out << indent() << "if " << context.tgt << " == src {" << '\n'; } else { out << indent() << "if " << context.tgt << " == "; if (values[0]->is_field_reference()) { @@ -608,18 +608,18 @@ void go_validator_generator::generate_integer_field_validator(std::ostream& out, } else { out << values[0]->get_int(); } - out << "{" << endl; + out << "{" << '\n'; } indent_up(); out << indent() << "return thrift.NewValidationException(thrift.VALIDATION_FAILED, \"vt.not_in\", \"" << context.field_symbol << "\", \"" << context.field_symbol - << " not valid, rule vt.not_in check failed\")" << endl; + << " not valid, rule vt.not_in check failed\")" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; if (values.size() > 1) { indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } } } @@ -635,7 +635,7 @@ void go_validator_generator::generate_string_field_validator(std::ostream& out, if (type->is_binary()) { target = GenID("_tgt"); out << indent() << target << " := " - << "string(" << context.tgt << ")" << endl; + << "string(" << context.tgt << ")" << '\n'; } for (auto it = context.rules.begin(); it != context.rules.end(); it++) { const std::vector& values = (*it)->get_values(); @@ -729,14 +729,14 @@ void go_validator_generator::generate_string_field_validator(std::ostream& out, } out << ")"; } - out << "{" << endl; + out << "{" << '\n'; indent_up(); out << indent() << "return thrift.NewValidationException(thrift.VALIDATION_FAILED, \"" + key + "\", \"" << context.field_symbol << "\", \"" << context.field_symbol << " not valid, rule " << key - << " check failed\")" << endl; + << " check failed\")" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } } @@ -764,19 +764,19 @@ void go_validator_generator::generate_list_field_validator(std::ostream& out, } else { out << values[0]->get_int(); } - out << "{" << endl; + out << "{" << '\n'; indent_up(); out << indent() << "return thrift.NewValidationException(thrift.VALIDATION_FAILED, \"" + key + "\", \"" << context.field_symbol << "\", \"" << context.field_symbol << " not valid, rule " << key - << " check failed\")" << endl; + << " check failed\")" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } else if (key == "vt.elem") { - out << indent() << "for i := 0; i < len(" << context.tgt << ");i++ {" << endl; + out << indent() << "for i := 0; i < len(" << context.tgt << ");i++ {" << '\n'; indent_up(); std::string src = GenID("_elem"); - out << indent() << src << " := " << context.tgt << "[i]" << endl; + out << indent() << src << " := " << context.tgt << "[i]" << '\n'; t_type* elem_type; if (context.type->is_list()) { elem_type = ((t_list*)context.type)->get_elem_type(); @@ -791,7 +791,7 @@ void go_validator_generator::generate_list_field_validator(std::ostream& out, std::vector{(*it)->get_inner()}}; generate_field_validator(out, ctx); indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } } } @@ -815,17 +815,17 @@ void go_validator_generator::generate_map_field_validator(std::ostream& out, } else { out << values[0]->get_int(); } - out << "{" << endl; + out << "{" << '\n'; indent_up(); out << indent() << "return thrift.NewValidationException(thrift.VALIDATION_FAILED, \"" + key + "\", \"" << context.field_symbol << "\", \"" << context.field_symbol << " not valid, rule " << key - << " check failed\")" << endl; + << " check failed\")" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } else if (key == "vt.key") { std::string src = GenID("_key"); - out << indent() << "for " << src << " := range " << context.tgt << " {" << endl; + out << indent() << "for " << src << " := range " << context.tgt << " {" << '\n'; indent_up(); generator_context ctx{context.field_symbol + ".key", "", @@ -835,10 +835,10 @@ void go_validator_generator::generate_map_field_validator(std::ostream& out, std::vector{(*it)->get_inner()}}; generate_field_validator(out, ctx); indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } else if (key == "vt.value") { std::string src = GenID("_value"); - out << indent() << "for _, " << src << " := range " << context.tgt << " {" << endl; + out << indent() << "for _, " << src << " := range " << context.tgt << " {" << '\n'; indent_up(); generator_context ctx{context.field_symbol + ".value", "", @@ -848,7 +848,7 @@ void go_validator_generator::generate_map_field_validator(std::ostream& out, std::vector{(*it)->get_inner()}}; generate_field_validator(out, ctx); indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } } } @@ -875,31 +875,31 @@ void go_validator_generator::generate_struct_field_validator(std::ostream& out, } if (generate_valid) { if (last_valid_rule == nullptr) { - out << indent() << "if err := " << context.tgt << ".Validate(); err != nil {" << endl; + out << indent() << "if err := " << context.tgt << ".Validate(); err != nil {" << '\n'; indent_up(); - out << indent() << "return err" << endl; + out << indent() << "return err" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } else { const std::vector& values = last_valid_rule->get_values(); if (!values[0]->get_bool()) { - out << indent() << "if err := " << context.tgt << ".Validate(); err != nil {" << endl; + out << indent() << "if err := " << context.tgt << ".Validate(); err != nil {" << '\n'; indent_up(); - out << indent() << "return err" << endl; + out << indent() << "return err" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } else if (values[0]->is_field_reference()) { out << indent() << "if !"; out << get_field_reference_name(values[0]->get_field_reference()); - out << "{" << endl; + out << "{" << '\n'; indent_up(); - out << indent() << "if err := " << context.tgt << ".Validate(); err != nil {" << endl; + out << indent() << "if err := " << context.tgt << ".Validate(); err != nil {" << '\n'; indent_up(); - out << indent() << "return err" << endl; + out << indent() << "return err" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } } } 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 da25338493c..b5eb6032891 100644 --- a/compiler/cpp/src/thrift/generate/t_c_glib_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_c_glib_generator.cc @@ -39,8 +39,6 @@ using std::string; using std::stringstream; using std::vector; -static const string endl = "\n"; // avoid ostream << std::endl flushes - /* forward declarations */ string initial_caps_to_underscores(string name); string underscores_to_initial_caps(string name); @@ -241,18 +239,18 @@ void t_c_glib_generator::init_generator() { f_types_impl_ << autogen_comment(); /* include inclusion guard */ - f_types_ << "#ifndef " << this->nspace_uc << program_name_uc << "_TYPES_H" << endl << "#define " - << this->nspace_uc << program_name_uc << "_TYPES_H" << endl << endl; + f_types_ << "#ifndef " << this->nspace_uc << program_name_uc << "_TYPES_H" << '\n' << "#define " + << this->nspace_uc << program_name_uc << "_TYPES_H" << '\n' << '\n'; /* include base types */ - f_types_ << "/* base includes */" << endl << "#include " << endl - << "#include " << endl - << "#include " << endl; + f_types_ << "/* base includes */" << '\n' << "#include " << '\n' + << "#include " << '\n' + << "#include " << '\n'; /* include other thrift includes */ const vector& includes = program_->get_includes(); if (!includes.empty()) { - f_types_ << "/* other thrift includes */" << endl; + f_types_ << "/* other thrift includes */" << '\n'; for (auto include : includes) { const std::string& include_nspace = include->get_namespace("c_glib"); @@ -260,32 +258,32 @@ void t_c_glib_generator::init_generator() { include_nspace.empty() ? "" : initial_caps_to_underscores(include_nspace) + "_"; f_types_ << "#include \"" << include_nspace_prefix - << initial_caps_to_underscores(include->get_name()) << "_types.h\"" << endl; + << initial_caps_to_underscores(include->get_name()) << "_types.h\"" << '\n'; } - f_types_ << endl; + f_types_ << '\n'; } /* include custom headers */ const vector& c_includes = program_->get_c_includes(); - f_types_ << "/* custom thrift includes */" << endl; + f_types_ << "/* custom thrift includes */" << '\n'; for (const auto & c_include : c_includes) { if (c_include[0] == '<') { - f_types_ << "#include " << c_include << endl; + f_types_ << "#include " << c_include << '\n'; } else { - f_types_ << "#include \"" << c_include << "\"" << endl; + f_types_ << "#include \"" << c_include << "\"" << '\n'; } } - f_types_ << endl; + f_types_ << '\n'; /* include math.h (for "INFINITY") in the implementation file, in case we encounter a struct with a member of type double */ - f_types_impl_ << endl << "#include " << endl; + f_types_impl_ << '\n' << "#include " << '\n'; // include the types file - f_types_impl_ << endl << "#include \"" << this->nspace_lc << program_name_u << "_types.h\"" - << endl << "#include " << endl << endl; + f_types_impl_ << '\n' << "#include \"" << this->nspace_lc << program_name_u << "_types.h\"" + << '\n' << "#include " << '\n' << '\n'; - f_types_ << "/* begin types */" << endl << endl; + f_types_ << "/* begin types */" << '\n' << '\n'; } /** @@ -295,7 +293,7 @@ void t_c_glib_generator::close_generator() { string program_name_uc = to_upper_case(initial_caps_to_underscores(program_name_)); /* end the header inclusion guard */ - f_types_ << "#endif /* " << this->nspace_uc << program_name_uc << "_TYPES_H */" << endl; + f_types_ << "#endif /* " << this->nspace_uc << program_name_uc << "_TYPES_H */" << '\n'; /* close output file */ f_types_.close(); @@ -313,7 +311,7 @@ void t_c_glib_generator::close_generator() { */ void t_c_glib_generator::generate_typedef(t_typedef* ttypedef) { f_types_ << indent() << "typedef " << type_name(ttypedef->get_type(), true) << " " << this->nspace - << ttypedef->get_symbolic() << ";" << endl << endl; + << ttypedef->get_symbolic() << ";" << '\n' << '\n'; } /** @@ -336,7 +334,7 @@ void t_c_glib_generator::generate_enum(t_enum* tenum) { string name = tenum->get_name(); string name_uc = to_upper_case(initial_caps_to_underscores(name)); - f_types_ << indent() << "enum _" << this->nspace << name << " {" << endl; + f_types_ << indent() << "enum _" << this->nspace << name << " {" << '\n'; indent_up(); @@ -349,7 +347,7 @@ void t_c_glib_generator::generate_enum(t_enum* tenum) { if (first) { first = false; } else { - f_types_ << "," << endl; + f_types_ << "," << '\n'; } f_types_ << indent() << this->nspace_uc << name_uc << "_" << (*c_iter)->get_name(); @@ -357,19 +355,19 @@ void t_c_glib_generator::generate_enum(t_enum* tenum) { } indent_down(); - f_types_ << endl << "};" << endl << "typedef enum _" << this->nspace << name << " " - << this->nspace << name << ";" << endl << endl; + f_types_ << '\n' << "};" << '\n' << "typedef enum _" << this->nspace << name << " " + << this->nspace << name << ";" << '\n' << '\n'; - f_types_ << "/* return the name of the constant */" << endl; - f_types_ << "const char *" << endl; - f_types_ << "toString_" << name << "(int value); " << endl << endl; + f_types_ << "/* return the name of the constant */" << '\n'; + f_types_ << "const char *" << '\n'; + f_types_ << "toString_" << name << "(int value); " << '\n' << '\n'; ; - f_types_impl_ << "/* return the name of the constant */" << endl; - f_types_impl_ << "const char *" << endl; - f_types_impl_ << "toString_" << name << "(int value) " << endl; - f_types_impl_ << "{" << endl; - f_types_impl_ << " static __thread char buf[16] = {0};" << endl; - f_types_impl_ << " switch(value) {" << endl; + f_types_impl_ << "/* return the name of the constant */" << '\n'; + f_types_impl_ << "const char *" << '\n'; + f_types_impl_ << "toString_" << name << "(int value) " << '\n'; + f_types_impl_ << "{" << '\n'; + f_types_impl_ << " static __thread char buf[16] = {0};" << '\n'; + f_types_impl_ << " switch(value) {" << '\n'; std::set done; for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) { int value = (*c_iter)->get_value(); @@ -379,20 +377,20 @@ void t_c_glib_generator::generate_enum(t_enum* tenum) { f_types_impl_ << " case " << this->nspace_uc << name_uc << "_" << (*c_iter)->get_name() << ":" << "return \"" << this->nspace_uc << name_uc << "_" << (*c_iter)->get_name() - << "\";" << endl; + << "\";" << '\n'; } } - f_types_impl_ << " default: g_snprintf(buf, 16, \"%d\", value); return buf;" << endl; - f_types_impl_ << " }" << endl; - f_types_impl_ << "}" << endl << endl; + f_types_impl_ << " default: g_snprintf(buf, 16, \"%d\", value); return buf;" << '\n'; + f_types_impl_ << " }" << '\n'; + f_types_impl_ << "}" << '\n' << '\n'; } /** * Generates Thrift constants in C code. */ void t_c_glib_generator::generate_consts(vector consts) { - f_types_ << "/* constants */" << endl; - f_types_impl_ << "/* constants */" << endl; + f_types_ << "/* constants */" << '\n'; + f_types_impl_ << "/* constants */" << '\n'; vector::iterator c_iter; for (c_iter = consts.begin(); c_iter != consts.end(); ++c_iter) { @@ -404,17 +402,17 @@ void t_c_glib_generator::generate_consts(vector consts) { if (is_complex_type(type)) { f_types_ << type_name(type) << indent() << this->nspace_lc << name_lc - << "_constant();" << endl; + << "_constant();" << '\n'; } f_types_ << indent() << "#define " << this->nspace_uc << name_uc << " " - << constant_value(name_lc, type, value) << endl; + << constant_value(name_lc, type, value) << '\n'; generate_const_initializer(name_lc, type, value, true); } - f_types_ << endl; - f_types_impl_ << endl; + f_types_ << '\n'; + f_types_impl_ << '\n'; } /** @@ -439,7 +437,7 @@ void t_c_glib_generator::generate_consts(vector consts) { * // ... additional GObject boilerplate ... */ void t_c_glib_generator::generate_struct(t_struct* tstruct) { - f_types_ << "/* struct " << tstruct->get_name() << " */" << endl; + f_types_ << "/* struct " << tstruct->get_name() << " */" << '\n'; generate_object(tstruct); } @@ -463,21 +461,21 @@ void t_c_glib_generator::generate_service(t_service* tservice) { f_header_ << autogen_comment(); // add an inclusion guard - f_header_ << "#ifndef " << svcname_uc << "_H" << endl << "#define " << svcname_uc << "_H" << endl - << endl; + f_header_ << "#ifndef " << svcname_uc << "_H" << '\n' << "#define " << svcname_uc << "_H" << '\n' + << '\n'; // add standard includes - f_header_ << "#include " << endl << endl; - f_header_ << "#include \"" << this->nspace_lc << program_name_lc << "_types.h\"" << endl; + f_header_ << "#include " << '\n' << '\n'; + f_header_ << "#include \"" << this->nspace_lc << program_name_lc << "_types.h\"" << '\n'; // if we are inheriting from another service, include its header t_service* extends_service = tservice->get_extends(); if (extends_service != nullptr) { f_header_ << "#include \"" << this->nspace_lc << to_lower_case(initial_caps_to_underscores(extends_service->get_name())) << ".h\"" - << endl; + << '\n'; } - f_header_ << endl; + f_header_ << '\n'; // create the service implementation string f_service_name = get_out_dir() + filename + ".c"; @@ -487,9 +485,9 @@ void t_c_glib_generator::generate_service(t_service* tservice) { f_service_ << autogen_comment(); // include the headers - f_service_ << "#include " << endl << "#include " << endl - << "#include " << endl << "#include \"" - << filename << ".h\"" << endl << endl; + f_service_ << "#include " << '\n' << "#include " << '\n' + << "#include " << '\n' << "#include \"" + << filename << ".h\"" << '\n' << '\n'; // generate the service-helper classes generate_service_helpers(tservice); @@ -501,7 +499,7 @@ void t_c_glib_generator::generate_service(t_service* tservice) { generate_service_server(tservice); // end the header inclusion guard - f_header_ << "#endif /* " << svcname_uc << "_H */" << endl; + f_header_ << "#endif /* " << svcname_uc << "_H */" << '\n'; // close the files f_service_.close(); @@ -519,27 +517,27 @@ void t_c_glib_generator::generate_xception(t_struct* tstruct) { generate_object(tstruct); - f_types_ << "/* exception */" << endl - << "typedef enum" << endl - << "{" << endl; + f_types_ << "/* exception */" << '\n' + << "typedef enum" << '\n' + << "{" << '\n'; indent_up(); - f_types_ << indent() << this->nspace_uc << name_uc << "_ERROR_CODE" << endl; + f_types_ << indent() << this->nspace_uc << name_uc << "_ERROR_CODE" << '\n'; indent_down(); - f_types_ << "} " << this->nspace << name << "Error;" << endl - << endl + f_types_ << "} " << this->nspace << name << "Error;" << '\n' + << '\n' << "GQuark " << this->nspace_lc << name_lc - << "_error_quark (void);" << endl + << "_error_quark (void);" << '\n' << "#define " << this->nspace_uc << name_uc << "_ERROR (" - << this->nspace_lc << name_lc << "_error_quark())" << endl - << endl - << endl; + << this->nspace_lc << name_lc << "_error_quark())" << '\n' + << '\n' + << '\n'; - f_types_impl_ << "/* define the GError domain for exceptions */" << endl << "#define " + f_types_impl_ << "/* define the GError domain for exceptions */" << '\n' << "#define " << this->nspace_uc << name_uc << "_ERROR_DOMAIN \"" << this->nspace_lc << name_lc - << "_error_quark\"" << endl << "GQuark" << endl << this->nspace_lc << name_lc - << "_error_quark (void)" << endl << "{" << endl + << "_error_quark\"" << '\n' << "GQuark" << '\n' << this->nspace_lc << name_lc + << "_error_quark (void)" << '\n' << "{" << '\n' << " return g_quark_from_static_string (" << this->nspace_uc << name_uc - << "_ERROR_DOMAIN);" << endl << "}" << endl << endl; + << "_ERROR_DOMAIN);" << '\n' << "}" << '\n' << '\n'; } /******************** @@ -983,12 +981,12 @@ string t_c_glib_generator::constant_value_with_storage(string fname, ostringstream render; if (is_numeric(etype)) { render << " " << type_name(etype) << " *" << fname << " = " - << "g_new (" << base_type_name(etype) << ", 1);" << endl + << "g_new (" << base_type_name(etype) << ", 1);" << '\n' << " *" << fname << " = " << constant_value(fname, (t_type*)etype, value) << ";" - << endl; + << '\n'; } else { render << " " << type_name(etype) << " " << fname << " = " - << constant_value(fname, (t_type*)etype, value) << ";" << endl; + << constant_value(fname, (t_type*)etype, value) << ";" << '\n'; } return render.str(); } @@ -1037,22 +1035,22 @@ void t_c_glib_generator::generate_const_initializer(string name, initializers << " constant->" << v_iter->first->get_string() << " = " << constant_value(name + "_constant_" + field_name, field_type, - v_iter->second) << ";" << endl + v_iter->second) << ";" << '\n' << " constant->__isset_" << v_iter->first->get_string() - << " = TRUE;" << endl; + << " = TRUE;" << '\n'; } // implement the initializer f_types_impl_ << maybe_static << this->nspace << type->get_name() << " *" - << endl - << this->nspace_lc << name_lc << "_constant (void)" << endl; + << '\n' + << this->nspace_lc << name_lc << "_constant (void)" << '\n'; scope_up(f_types_impl_); f_types_impl_ << indent() << "static " << this->nspace << type->get_name() - << " *constant = NULL;" << endl - << indent() << "if (constant == NULL)" << endl; + << " *constant = NULL;" << '\n' + << indent() << "if (constant == NULL)" << '\n'; scope_up(f_types_impl_); f_types_impl_ << indent() << "constant = g_object_new (" << this->nspace_uc - << "TYPE_" << type_uc << ", NULL);" << endl + << "TYPE_" << type_uc << ", NULL);" << '\n' << initializers.str(); scope_down(f_types_impl_); @@ -1074,9 +1072,9 @@ void t_c_glib_generator::generate_const_initializer(string name, field_name = tmp(field_name); } - f_types_impl_ << indent() << "return constant;" << endl; + f_types_impl_ << indent() << "return constant;" << '\n'; scope_down(f_types_impl_); - f_types_impl_ << endl; + f_types_impl_ << '\n'; } else if (type->is_list()) { string list_type = "GPtrArray *"; string free_func @@ -1125,33 +1123,33 @@ void t_c_glib_generator::generate_const_initializer(string name, if (list_variable) { initializers << " " << type_name(etype) << " " << fname << " = " << constant_value(fname, (t_type*)etype, (*v_iter)) << ";" - << endl; + << '\n'; appenders << " " << list_appender << "(constant, " << fname << ");" - << endl; + << '\n'; } else { appenders << " " << list_appender << "(constant, " << constant_value(fname, (t_type*)etype, (*v_iter)) << ");" - << endl; + << '\n'; } } - f_types_impl_ << maybe_static << list_type << endl - << this->nspace_lc << name_lc << "_constant (void)" << endl; + f_types_impl_ << maybe_static << list_type << '\n' + << this->nspace_lc << name_lc << "_constant (void)" << '\n'; scope_up(f_types_impl_); f_types_impl_ << indent() << "static " << list_type << " constant = NULL;" - << endl - << indent() << "if (constant == NULL)" << endl; + << '\n' + << indent() << "if (constant == NULL)" << '\n'; scope_up(f_types_impl_); if (!initializers.str().empty()) { f_types_impl_ << initializers.str() - << endl; + << '\n'; } - f_types_impl_ << indent() << "constant = " << list_initializer << endl + f_types_impl_ << indent() << "constant = " << list_initializer << '\n' << appenders.str(); scope_down(f_types_impl_); - f_types_impl_ << indent() << "return constant;" << endl; + f_types_impl_ << indent() << "return constant;" << '\n'; scope_down(f_types_impl_); - f_types_impl_ << endl; + f_types_impl_ << '\n'; } else if (type->is_set()) { t_type* etype = ((t_set*)type)->get_elem_type(); const vector& val = value->get_list(); @@ -1164,22 +1162,22 @@ void t_c_glib_generator::generate_const_initializer(string name, string ptr = is_numeric(etype) ? "*" : ""; generate_const_initializer(fname, etype, (*v_iter)); initializers << constant_value_with_storage(fname, (t_type*)etype, *v_iter); - appenders << " g_hash_table_insert (constant, " << fname << ", 0);" << endl; + appenders << " g_hash_table_insert (constant, " << fname << ", 0);" << '\n'; } - f_types_impl_ << maybe_static << "GHashTable *" << endl - << this->nspace_lc << name_lc << "_constant (void)" << endl; + f_types_impl_ << maybe_static << "GHashTable *" << '\n' + << this->nspace_lc << name_lc << "_constant (void)" << '\n'; scope_up(f_types_impl_); - f_types_impl_ << indent() << "static GHashTable *constant = NULL;" << endl - << indent() << "if (constant == NULL)" << endl; + f_types_impl_ << indent() << "static GHashTable *constant = NULL;" << '\n' + << indent() << "if (constant == NULL)" << '\n'; scope_up(f_types_impl_); - f_types_impl_ << initializers.str() << endl - << indent() << "constant = " << generate_new_hash_from_type(etype, nullptr) << endl + f_types_impl_ << initializers.str() << '\n' + << indent() << "constant = " << generate_new_hash_from_type(etype, nullptr) << '\n' << appenders.str(); scope_down(f_types_impl_); - f_types_impl_ << indent() << "return constant;" << endl; + f_types_impl_ << indent() << "return constant;" << '\n'; scope_down(f_types_impl_); - f_types_impl_ << endl; + f_types_impl_ << '\n'; } else if (type->is_map()) { t_type* ktype = ((t_map*)type)->get_key_type(); t_type* vtype = ((t_map*)type)->get_val_type(); @@ -1197,22 +1195,22 @@ void t_c_glib_generator::generate_const_initializer(string name, initializers << constant_value_with_storage(kname, (t_type*)ktype, v_iter->first); initializers << constant_value_with_storage(vname, (t_type*)vtype, v_iter->second); - appenders << " g_hash_table_insert (constant, " << kname << ", " << vname << ");" << endl; + appenders << " g_hash_table_insert (constant, " << kname << ", " << vname << ");" << '\n'; } - f_types_impl_ << maybe_static << "GHashTable *" << endl - << this->nspace_lc << name_lc << "_constant (void)" << endl; + f_types_impl_ << maybe_static << "GHashTable *" << '\n' + << this->nspace_lc << name_lc << "_constant (void)" << '\n'; scope_up(f_types_impl_); - f_types_impl_ << indent() << "static GHashTable *constant = NULL;" << endl - << indent() << "if (constant == NULL)" << endl; + f_types_impl_ << indent() << "static GHashTable *constant = NULL;" << '\n' + << indent() << "if (constant == NULL)" << '\n'; scope_up(f_types_impl_); - f_types_impl_ << initializers.str() << endl - << indent() << "constant = " << generate_new_hash_from_type(ktype, vtype) << endl + f_types_impl_ << initializers.str() << '\n' + << indent() << "constant = " << generate_new_hash_from_type(ktype, vtype) << '\n' << appenders.str(); scope_down(f_types_impl_); - f_types_impl_ << indent() << "return constant;" << endl; + f_types_impl_ << indent() << "return constant;" << '\n'; scope_down(f_types_impl_); - f_types_impl_ << endl; + f_types_impl_ << '\n'; } } @@ -1303,13 +1301,13 @@ void t_c_glib_generator::generate_service_client(t_service* tservice) { string base_service_name_uc = to_upper_case(base_service_name_lc); // Generate the client interface dummy object in the header. - f_header_ << "/* " << service_name_ << " service interface */" << endl << "typedef struct _" + f_header_ << "/* " << service_name_ << " service interface */" << '\n' << "typedef struct _" << this->nspace << service_name_ << "If " << this->nspace << service_name_ << "If; " - << " /* dummy object */" << endl << endl; + << " /* dummy object */" << '\n' << '\n'; // Generate the client interface object in the header. - f_header_ << "struct _" << this->nspace << service_name_ << "IfInterface" << endl << "{" << endl - << " GTypeInterface parent;" << endl << endl; + f_header_ << "struct _" << this->nspace << service_name_ << "IfInterface" << '\n' << "{" << '\n' + << " GTypeInterface parent;" << '\n' << '\n'; /* write out the functions for this interface */ indent_up(); @@ -1330,26 +1328,26 @@ void t_c_glib_generator::generate_service_client(t_service* tservice) { + (has_args ? "" : (", " + argument_list(arglist))) + (has_xceptions ? "" : (", " + xception_list(xlist))) + ", GError **error)"; - indent(f_header_) << "gboolean (*" << funname << ") " << params << ";" << endl; + indent(f_header_) << "gboolean (*" << funname << ") " << params << ";" << '\n'; } indent_down(); - f_header_ << "};" << endl << "typedef struct _" << this->nspace << service_name_ << "IfInterface " - << this->nspace << service_name_ << "IfInterface;" << endl << endl; + f_header_ << "};" << '\n' << "typedef struct _" << this->nspace << service_name_ << "IfInterface " + << this->nspace << service_name_ << "IfInterface;" << '\n' << '\n'; // generate all the interface boilerplate - f_header_ << "GType " << this->nspace_lc << service_name_lc << "_if_get_type (void);" << endl + f_header_ << "GType " << this->nspace_lc << service_name_lc << "_if_get_type (void);" << '\n' << "#define " << this->nspace_uc << "TYPE_" << service_name_uc << "_IF " - << "(" << this->nspace_lc << service_name_lc << "_if_get_type())" << endl << "#define " + << "(" << this->nspace_lc << service_name_lc << "_if_get_type())" << '\n' << "#define " << this->nspace_uc << service_name_uc << "_IF(obj) " << "(G_TYPE_CHECK_INSTANCE_CAST ((obj), " << this->nspace_uc << "TYPE_" - << service_name_uc << "_IF, " << this->nspace << service_name_ << "If))" << endl + << service_name_uc << "_IF, " << this->nspace << service_name_ << "If))" << '\n' << "#define " << this->nspace_uc << "IS_" << service_name_uc << "_IF(obj) " << "(G_TYPE_CHECK_INSTANCE_TYPE ((obj), " << this->nspace_uc << "TYPE_" - << service_name_uc << "_IF))" << endl << "#define " << this->nspace_uc + << service_name_uc << "_IF))" << '\n' << "#define " << this->nspace_uc << service_name_uc << "_IF_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), " << this->nspace_uc << "TYPE_" << service_name_uc << "_IF, " << this->nspace - << service_name_ << "IfInterface))" << endl << endl; + << service_name_ << "IfInterface))" << '\n' << '\n'; // write out all the interface function prototypes for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { @@ -1368,50 +1366,50 @@ void t_c_glib_generator::generate_service_client(t_service* tservice) { + (has_xceptions ? "" : (", " + xception_list(xlist))) + ", GError **error)"; f_header_ << "gboolean " << this->nspace_lc << service_name_lc << "_if_" << funname << " " - << params << ";" << endl; + << params << ";" << '\n'; } - f_header_ << endl; + f_header_ << '\n'; // Generate the client object instance definition in the header. - f_header_ << "/* " << service_name_ << " service client */" << endl << "struct _" << this->nspace - << service_name_ << "Client" << endl << "{" << endl << " " << parent_class_name - << " parent;" << endl; + f_header_ << "/* " << service_name_ << " service client */" << '\n' << "struct _" << this->nspace + << service_name_ << "Client" << '\n' << "{" << '\n' << " " << parent_class_name + << " parent;" << '\n'; if (!extends_service) { // Define "input_protocol" and "output_protocol" properties only // for base services; child service-client classes will inherit // these - f_header_ << endl << " ThriftProtocol *input_protocol;" << endl - << " ThriftProtocol *output_protocol;" << endl; + f_header_ << '\n' << " ThriftProtocol *input_protocol;" << '\n' + << " ThriftProtocol *output_protocol;" << '\n'; } - f_header_ << "};" << endl << "typedef struct _" << this->nspace << service_name_ << "Client " - << this->nspace << service_name_ << "Client;" << endl << endl; + f_header_ << "};" << '\n' << "typedef struct _" << this->nspace << service_name_ << "Client " + << this->nspace << service_name_ << "Client;" << '\n' << '\n'; // Generate the class definition in the header. - f_header_ << "struct _" << this->nspace << service_name_ << "ClientClass" << endl << "{" << endl - << " " << parent_class_name << "Class parent;" << endl << "};" << endl + f_header_ << "struct _" << this->nspace << service_name_ << "ClientClass" << '\n' << "{" << '\n' + << " " << parent_class_name << "Class parent;" << '\n' << "};" << '\n' << "typedef struct _" << this->nspace << service_name_ << "ClientClass " << this->nspace - << service_name_ << "ClientClass;" << endl << endl; + << service_name_ << "ClientClass;" << '\n' << '\n'; // Create all the GObject boilerplate - f_header_ << "GType " << this->nspace_lc << service_name_lc << "_client_get_type (void);" << endl + f_header_ << "GType " << this->nspace_lc << service_name_lc << "_client_get_type (void);" << '\n' << "#define " << this->nspace_uc << "TYPE_" << service_name_uc << "_CLIENT " - << "(" << this->nspace_lc << service_name_lc << "_client_get_type())" << endl + << "(" << this->nspace_lc << service_name_lc << "_client_get_type())" << '\n' << "#define " << this->nspace_uc << service_name_uc << "_CLIENT(obj) " << "(G_TYPE_CHECK_INSTANCE_CAST ((obj), " << this->nspace_uc << "TYPE_" - << service_name_uc << "_CLIENT, " << this->nspace << service_name_ << "Client))" << endl + << service_name_uc << "_CLIENT, " << this->nspace << service_name_ << "Client))" << '\n' << "#define " << this->nspace_uc << service_name_uc << "_CLIENT_CLASS(c) " << "(G_TYPE_CHECK_CLASS_CAST ((c), " << this->nspace_uc << "TYPE_" << service_name_uc - << "_CLIENT, " << this->nspace << service_name_ << "ClientClass))" << endl << "#define " + << "_CLIENT, " << this->nspace << service_name_ << "ClientClass))" << '\n' << "#define " << this->nspace_uc << service_name_uc << "_IS_CLIENT(obj) " << "(G_TYPE_CHECK_INSTANCE_TYPE ((obj), " << this->nspace_uc << "TYPE_" - << service_name_uc << "_CLIENT))" << endl << "#define " << this->nspace_uc + << service_name_uc << "_CLIENT))" << '\n' << "#define " << this->nspace_uc << service_name_uc << "_IS_CLIENT_CLASS(c) " << "(G_TYPE_CHECK_CLASS_TYPE ((c), " << this->nspace_uc << "TYPE_" << service_name_uc - << "_CLIENT))" << endl << "#define " << this->nspace_uc << service_name_uc + << "_CLIENT))" << '\n' << "#define " << this->nspace_uc << service_name_uc << "_CLIENT_GET_CLASS(obj) " << "(G_TYPE_INSTANCE_GET_CLASS ((obj), " << this->nspace_uc << "TYPE_" << service_name_uc << "_CLIENT, " << this->nspace << service_name_ << "ClientClass))" - << endl << endl; + << '\n' << '\n'; /* write out the function prototypes */ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { @@ -1422,12 +1420,12 @@ void t_c_glib_generator::generate_service_client(t_service* tservice) { service_name_lc + string("_client_") + funname, (*f_iter)->get_arglist(), (*f_iter)->get_xceptions()); - indent(f_header_) << function_signature(&service_function) << ";" << endl; + indent(f_header_) << function_signature(&service_function) << ";" << '\n'; t_function send_function(g_type_void, service_name_lc + string("_client_send_") + funname, (*f_iter)->get_arglist()); - indent(f_header_) << function_signature(&send_function) << ";" << endl; + indent(f_header_) << function_signature(&send_function) << ";" << '\n'; // implement recv if not a oneway service if (!(*f_iter)->is_oneway()) { @@ -1436,19 +1434,19 @@ void t_c_glib_generator::generate_service_client(t_service* tservice) { service_name_lc + string("_client_recv_") + funname, &noargs, (*f_iter)->get_xceptions()); - indent(f_header_) << function_signature(&recv_function) << ";" << endl; + indent(f_header_) << function_signature(&recv_function) << ";" << '\n'; } } /* write out the get/set function prototypes */ f_header_ << "void " + service_name_lc + "_client_set_property (GObject *object, guint " "property_id, const GValue *value, GParamSpec *pspec);" - << endl; + << '\n'; f_header_ << "void " + service_name_lc + "_client_get_property (GObject *object, guint " "property_id, GValue *value, GParamSpec *pspec);" - << endl; + << '\n'; - f_header_ << endl; + f_header_ << '\n'; // end of header code // Generate interface method implementations @@ -1483,76 +1481,76 @@ void t_c_glib_generator::generate_service_client(t_service* tservice) { params_without_type += ", "; } - f_service_ << "gboolean" << endl << this->nspace_lc << service_name_lc << "_if_" << funname - << " " << params << endl << "{" << endl << " return " << this->nspace_uc + f_service_ << "gboolean" << '\n' << this->nspace_lc << service_name_lc << "_if_" << funname + << " " << params << '\n' << "{" << '\n' << " return " << this->nspace_uc << service_name_uc << "_IF_GET_INTERFACE (iface)->" << funname << " (" - << params_without_type << "error);" << endl << "}" << endl << endl; + << params_without_type << "error);" << '\n' << "}" << '\n' << '\n'; } // Generate interface boilerplate - f_service_ << "GType" << endl << this->nspace_lc << service_name_lc << "_if_get_type (void)" - << endl << "{" << endl << " static GType type = 0;" << endl << " if (type == 0)" - << endl << " {" << endl << " static const GTypeInfo type_info =" << endl << " {" - << endl << " sizeof (" << this->nspace << service_name_ << "IfInterface)," << endl - << " NULL, /* base_init */" << endl << " NULL, /* base_finalize */" << endl - << " NULL, /* class_init */" << endl << " NULL, /* class_finalize */" - << endl << " NULL, /* class_data */" << endl - << " 0, /* instance_size */" << endl << " 0, /* n_preallocs */" - << endl << " NULL, /* instance_init */" << endl - << " NULL /* value_table */" << endl << " };" << endl - << " type = g_type_register_static (G_TYPE_INTERFACE," << endl + f_service_ << "GType" << '\n' << this->nspace_lc << service_name_lc << "_if_get_type (void)" + << '\n' << "{" << '\n' << " static GType type = 0;" << '\n' << " if (type == 0)" + << '\n' << " {" << '\n' << " static const GTypeInfo type_info =" << '\n' << " {" + << '\n' << " sizeof (" << this->nspace << service_name_ << "IfInterface)," << '\n' + << " NULL, /* base_init */" << '\n' << " NULL, /* base_finalize */" << '\n' + << " NULL, /* class_init */" << '\n' << " NULL, /* class_finalize */" + << '\n' << " NULL, /* class_data */" << '\n' + << " 0, /* instance_size */" << '\n' << " 0, /* n_preallocs */" + << '\n' << " NULL, /* instance_init */" << '\n' + << " NULL /* value_table */" << '\n' << " };" << '\n' + << " type = g_type_register_static (G_TYPE_INTERFACE," << '\n' << " \"" << this->nspace << service_name_ << "If\"," - << endl << " &type_info, 0);" << endl << " }" - << endl << " return type;" << endl << "}" << endl << endl; + << '\n' << " &type_info, 0);" << '\n' << " }" + << '\n' << " return type;" << '\n' << "}" << '\n' << '\n'; // Generate client boilerplate - f_service_ << "static void " << endl << this->nspace_lc << service_name_lc + f_service_ << "static void " << '\n' << this->nspace_lc << service_name_lc << "_if_interface_init (" << this->nspace << service_name_ << "IfInterface *iface);" - << endl << endl << "G_DEFINE_TYPE_WITH_CODE (" << this->nspace << service_name_ - << "Client, " << this->nspace_lc << service_name_lc << "_client," << endl - << " " << parent_type_name << ", " << endl + << '\n' << '\n' << "G_DEFINE_TYPE_WITH_CODE (" << this->nspace << service_name_ + << "Client, " << this->nspace_lc << service_name_lc << "_client," << '\n' + << " " << parent_type_name << ", " << '\n' << " G_IMPLEMENT_INTERFACE (" << this->nspace_uc << "TYPE_" - << service_name_uc << "_IF," << endl + << service_name_uc << "_IF," << '\n' << " " << this->nspace_lc - << service_name_lc << "_if_interface_init))" << endl << endl; + << service_name_lc << "_if_interface_init))" << '\n' << '\n'; // Generate property-related code only for base services---child // service-client classes have only properties inherited from their // parent class if (!extends_service) { // Generate client properties - f_service_ << "enum _" << this->nspace << service_name_ << "ClientProperties" << endl << "{" - << endl << " PROP_0," << endl << " PROP_" << this->nspace_uc << service_name_uc - << "_CLIENT_INPUT_PROTOCOL," << endl << " PROP_" << this->nspace_uc - << service_name_uc << "_CLIENT_OUTPUT_PROTOCOL" << endl << "};" << endl << endl; + f_service_ << "enum _" << this->nspace << service_name_ << "ClientProperties" << '\n' << "{" + << '\n' << " PROP_0," << '\n' << " PROP_" << this->nspace_uc << service_name_uc + << "_CLIENT_INPUT_PROTOCOL," << '\n' << " PROP_" << this->nspace_uc + << service_name_uc << "_CLIENT_OUTPUT_PROTOCOL" << '\n' << "};" << '\n' << '\n'; // generate property setter - f_service_ << "void" << endl << this->nspace_lc << service_name_lc << "_client_set_property (" + f_service_ << "void" << '\n' << this->nspace_lc << service_name_lc << "_client_set_property (" << "GObject *object, guint property_id, const GValue *value, " - << "GParamSpec *pspec)" << endl << "{" << endl << " " << this->nspace + << "GParamSpec *pspec)" << '\n' << "{" << '\n' << " " << this->nspace << service_name_ << "Client *client = " << this->nspace_uc << service_name_uc - << "_CLIENT (object);" << endl << endl << " THRIFT_UNUSED_VAR (pspec);" << endl - << endl << " switch (property_id)" << endl << " {" << endl << " case PROP_" - << this->nspace_uc << service_name_uc << "_CLIENT_INPUT_PROTOCOL:" << endl - << " client->input_protocol = g_value_get_object (value);" << endl - << " break;" << endl << " case PROP_" << this->nspace_uc << service_name_uc - << "_CLIENT_OUTPUT_PROTOCOL:" << endl - << " client->output_protocol = g_value_get_object (value);" << endl - << " break;" << endl << " }" << endl << "}" << endl << endl; + << "_CLIENT (object);" << '\n' << '\n' << " THRIFT_UNUSED_VAR (pspec);" << '\n' + << '\n' << " switch (property_id)" << '\n' << " {" << '\n' << " case PROP_" + << this->nspace_uc << service_name_uc << "_CLIENT_INPUT_PROTOCOL:" << '\n' + << " client->input_protocol = g_value_get_object (value);" << '\n' + << " break;" << '\n' << " case PROP_" << this->nspace_uc << service_name_uc + << "_CLIENT_OUTPUT_PROTOCOL:" << '\n' + << " client->output_protocol = g_value_get_object (value);" << '\n' + << " break;" << '\n' << " }" << '\n' << "}" << '\n' << '\n'; // generate property getter - f_service_ << "void" << endl << this->nspace_lc << service_name_lc << "_client_get_property (" + f_service_ << "void" << '\n' << this->nspace_lc << service_name_lc << "_client_get_property (" << "GObject *object, guint property_id, GValue *value, " - << "GParamSpec *pspec)" << endl << "{" << endl << " " << this->nspace + << "GParamSpec *pspec)" << '\n' << "{" << '\n' << " " << this->nspace << service_name_ << "Client *client = " << this->nspace_uc << service_name_uc - << "_CLIENT (object);" << endl << endl << " THRIFT_UNUSED_VAR (pspec);" << endl - << endl << " switch (property_id)" << endl << " {" << endl << " case PROP_" - << this->nspace_uc << service_name_uc << "_CLIENT_INPUT_PROTOCOL:" << endl - << " g_value_set_object (value, client->input_protocol);" << endl - << " break;" << endl << " case PROP_" << this->nspace_uc << service_name_uc - << "_CLIENT_OUTPUT_PROTOCOL:" << endl - << " g_value_set_object (value, client->output_protocol);" << endl - << " break;" << endl << " }" << endl << "}" << endl << endl; + << "_CLIENT (object);" << '\n' << '\n' << " THRIFT_UNUSED_VAR (pspec);" << '\n' + << '\n' << " switch (property_id)" << '\n' << " {" << '\n' << " case PROP_" + << this->nspace_uc << service_name_uc << "_CLIENT_INPUT_PROTOCOL:" << '\n' + << " g_value_set_object (value, client->input_protocol);" << '\n' + << " break;" << '\n' << " case PROP_" << this->nspace_uc << service_name_uc + << "_CLIENT_OUTPUT_PROTOCOL:" << '\n' + << " g_value_set_object (value, client->output_protocol);" << '\n' + << " break;" << '\n' << " }" << '\n' << "}" << '\n' << '\n'; } // Generate client method implementations @@ -1569,31 +1567,31 @@ void t_c_glib_generator::generate_service_client(t_service* tservice) { (*f_iter)->get_arglist()); // Open the send function - indent(f_service_) << function_signature(&send_function) << endl; + indent(f_service_) << function_signature(&send_function) << '\n'; scope_up(f_service_); string reqType = (*f_iter)->is_oneway() ? "T_ONEWAY" : "T_CALL"; // Serialize the request - f_service_ << indent() << "gint32 cseqid = 0;" << endl << indent() + f_service_ << indent() << "gint32 cseqid = 0;" << '\n' << indent() << "ThriftProtocol * protocol = " << this->nspace_uc << base_service_name_uc - << "_CLIENT (iface)->output_protocol;" << endl << endl << indent() + << "_CLIENT (iface)->output_protocol;" << '\n' << '\n' << indent() << "if (thrift_protocol_write_message_begin (protocol, \"" << name << "\", " - << reqType << ", cseqid, error) < 0)" << endl << indent() << " return FALSE;" - << endl << endl; + << reqType << ", cseqid, error) < 0)" << '\n' << indent() << " return FALSE;" + << '\n' << '\n'; generate_struct_writer(f_service_, arg_struct, "", "", false); - f_service_ << indent() << "if (thrift_protocol_write_message_end (protocol, error) < 0)" << endl - << indent() << " return FALSE;" << endl << indent() - << "if (!thrift_transport_flush (protocol->transport, error))" << endl << indent() - << " return FALSE;" << endl << indent() - << "if (!thrift_transport_write_end (protocol->transport, error))" << endl - << indent() << " return FALSE;" << endl << endl << indent() << "return TRUE;" - << endl; + f_service_ << indent() << "if (thrift_protocol_write_message_end (protocol, error) < 0)" << '\n' + << indent() << " return FALSE;" << '\n' << indent() + << "if (!thrift_transport_flush (protocol->transport, error))" << '\n' << indent() + << " return FALSE;" << '\n' << indent() + << "if (!thrift_transport_write_end (protocol->transport, error))" << '\n' + << indent() << " return FALSE;" << '\n' << '\n' << indent() << "return TRUE;" + << '\n'; scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; // Generate recv function only if not an async function if (!(*f_iter)->is_oneway()) { @@ -1603,78 +1601,78 @@ void t_c_glib_generator::generate_service_client(t_service* tservice) { &noargs, (*f_iter)->get_xceptions()); // Open function - indent(f_service_) << function_signature(&recv_function) << endl; + indent(f_service_) << function_signature(&recv_function) << '\n'; scope_up(f_service_); - f_service_ << indent() << "gint32 rseqid;" << endl - << indent() << "gchar * fname = NULL;" << endl - << indent() << "ThriftMessageType mtype;" << endl + f_service_ << indent() << "gint32 rseqid;" << '\n' + << indent() << "gchar * fname = NULL;" << '\n' + << indent() << "ThriftMessageType mtype;" << '\n' << indent() << "ThriftProtocol * protocol = " << this->nspace_uc << base_service_name_uc - << "_CLIENT (iface)->input_protocol;" << endl - << indent() << "ThriftApplicationException *xception;" << endl - << endl + << "_CLIENT (iface)->input_protocol;" << '\n' + << indent() << "ThriftApplicationException *xception;" << '\n' + << '\n' << indent() << "if (thrift_protocol_read_message_begin " - "(protocol, &fname, &mtype, &rseqid, error) < 0) {" << endl; + "(protocol, &fname, &mtype, &rseqid, error) < 0) {" << '\n'; indent_up(); - f_service_ << indent() << "if (fname) g_free (fname);" << endl - << indent() << "return FALSE;" << endl; + f_service_ << indent() << "if (fname) g_free (fname);" << '\n' + << indent() << "return FALSE;" << '\n'; indent_down(); - f_service_ << indent() << "}" << endl - << endl - << indent() << "if (mtype == T_EXCEPTION) {" << endl; + f_service_ << indent() << "}" << '\n' + << '\n' + << indent() << "if (mtype == T_EXCEPTION) {" << '\n'; indent_up(); - f_service_ << indent() << "if (fname) g_free (fname);" << endl + f_service_ << indent() << "if (fname) g_free (fname);" << '\n' << indent() << "xception = g_object_new " - "(THRIFT_TYPE_APPLICATION_EXCEPTION, NULL);" << endl + "(THRIFT_TYPE_APPLICATION_EXCEPTION, NULL);" << '\n' << indent() << "thrift_struct_read (THRIFT_STRUCT (xception), " - "protocol, NULL);" << endl + "protocol, NULL);" << '\n' << indent() << "thrift_protocol_read_message_end " - "(protocol, NULL);" << endl + "(protocol, NULL);" << '\n' << indent() << "thrift_transport_read_end " - "(protocol->transport, NULL);" << endl + "(protocol->transport, NULL);" << '\n' << indent() << "g_set_error (error, " "THRIFT_APPLICATION_EXCEPTION_ERROR,xception->type, " - "\"application error: %s\", xception->message);" << endl - << indent() << "g_object_unref (xception);" << endl - << indent() << "return FALSE;" << endl; + "\"application error: %s\", xception->message);" << '\n' + << indent() << "g_object_unref (xception);" << '\n' + << indent() << "return FALSE;" << '\n'; indent_down(); - f_service_ << indent() << "} else if (mtype != T_REPLY) {" << endl; + f_service_ << indent() << "} else if (mtype != T_REPLY) {" << '\n'; indent_up(); - f_service_ << indent() << "if (fname) g_free (fname);" << endl + f_service_ << indent() << "if (fname) g_free (fname);" << '\n' << indent() << "thrift_protocol_skip (protocol, T_STRUCT, " - "NULL);" << endl + "NULL);" << '\n' << indent() << "thrift_protocol_read_message_end (protocol, " - "NULL);" << endl + "NULL);" << '\n' << indent() << "thrift_transport_read_end (" - "protocol->transport, NULL);" << endl + "protocol->transport, NULL);" << '\n' << indent() << "g_set_error (error, " "THRIFT_APPLICATION_EXCEPTION_ERROR, " "THRIFT_APPLICATION_EXCEPTION_ERROR_INVALID_MESSAGE_TYPE, " "\"invalid message type %d, expected T_REPLY\", mtype);" - << endl - << indent() << "return FALSE;" << endl; + << '\n' + << indent() << "return FALSE;" << '\n'; indent_down(); f_service_ << indent() << "} else if (strncmp (fname, \"" << name - << "\", " << name.length() << ") != 0) {" << endl; + << "\", " << name.length() << ") != 0) {" << '\n'; indent_up(); f_service_ << indent() << "thrift_protocol_skip (protocol, T_STRUCT, " - "NULL);" << endl + "NULL);" << '\n' << indent() << "thrift_protocol_read_message_end (protocol," - "error);" << endl + "error);" << '\n' << indent() << "thrift_transport_read_end (" - "protocol->transport, error);" << endl + "protocol->transport, error);" << '\n' << indent() << "g_set_error (error, " "THRIFT_APPLICATION_EXCEPTION_ERROR, " "THRIFT_APPLICATION_EXCEPTION_ERROR_WRONG_METHOD_NAME, " "\"wrong method name %s, expected " << name - << "\", fname);" << endl - << indent() << "if (fname) g_free (fname);" << endl - << indent() << "return FALSE;" << endl; + << "\", fname);" << '\n' + << indent() << "if (fname) g_free (fname);" << '\n' + << indent() << "return FALSE;" << '\n'; indent_down(); - f_service_ << indent() << "}" << endl - << indent() << "if (fname) g_free (fname);" << endl - << endl; + f_service_ << indent() << "}" << '\n' + << indent() << "if (fname) g_free (fname);" << '\n' + << '\n'; t_struct* xs = (*f_iter)->get_xceptions(); const std::vector& xceptions = xs->get_members(); @@ -1699,25 +1697,25 @@ void t_c_glib_generator::generate_service_client(t_service* tservice) { } f_service_ << indent() << "if (thrift_protocol_read_message_end (protocol, error) < 0)" - << endl << indent() << " return FALSE;" << endl << endl << indent() - << "if (!thrift_transport_read_end (protocol->transport, error))" << endl - << indent() << " return FALSE;" << endl << endl; + << '\n' << indent() << " return FALSE;" << '\n' << '\n' << indent() + << "if (!thrift_transport_read_end (protocol->transport, error))" << '\n' + << indent() << " return FALSE;" << '\n' << '\n'; // copy over any throw exceptions and return failure for (x_iter = xceptions.begin(); x_iter != xceptions.end(); x_iter++) { - f_service_ << indent() << "if (*" << (*x_iter)->get_name() << " != NULL)" << endl - << indent() << "{" << endl << indent() << " g_set_error (error, " + f_service_ << indent() << "if (*" << (*x_iter)->get_name() << " != NULL)" << '\n' + << indent() << "{" << '\n' << indent() << " g_set_error (error, " << this->nspace_uc << to_upper_case(initial_caps_to_underscores((*x_iter)->get_type()->get_name())) << "_ERROR, " << this->nspace_uc << to_upper_case(initial_caps_to_underscores((*x_iter)->get_type()->get_name())) - << "_ERROR_CODE, \"" << (*x_iter)->get_type()->get_name() << "\");" << endl - << indent() << " return FALSE;" << endl << indent() << "}" << endl; + << "_ERROR_CODE, \"" << (*x_iter)->get_type()->get_name() << "\");" << '\n' + << indent() << " return FALSE;" << '\n' << indent() << "}" << '\n'; } // Close function - indent(f_service_) << "return TRUE;" << endl; + indent(f_service_) << "return TRUE;" << '\n'; scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; } // Open function @@ -1725,7 +1723,7 @@ void t_c_glib_generator::generate_service_client(t_service* tservice) { service_name_lc + string("_client_") + funname, (*f_iter)->get_arglist(), (*f_iter)->get_xceptions()); - indent(f_service_) << function_signature(&service_function) << endl; + indent(f_service_) << function_signature(&service_function) << '\n'; scope_up(f_service_); // wrap each function @@ -1738,7 +1736,7 @@ void t_c_glib_generator::generate_service_client(t_service* tservice) { for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) { f_service_ << ", " << (*fld_iter)->get_name(); } - f_service_ << ", error))" << endl << indent() << " return FALSE;" << endl; + f_service_ << ", error))" << '\n' << indent() << " return FALSE;" << '\n'; // if not oneway, implement recv if (!(*f_iter)->is_oneway()) { @@ -1752,20 +1750,20 @@ void t_c_glib_generator::generate_service_client(t_service* tservice) { } f_service_ << indent() << "if (!" << this->nspace_lc << service_name_lc << "_client_recv_" - << funname << " (iface, " << ret << "error))" << endl << indent() - << " return FALSE;" << endl; + << funname << " (iface, " << ret << "error))" << '\n' << indent() + << " return FALSE;" << '\n'; } // return TRUE which means all functions were called OK - indent(f_service_) << "return TRUE;" << endl; + indent(f_service_) << "return TRUE;" << '\n'; scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; } // create the interface initializer - f_service_ << "static void" << endl + f_service_ << "static void" << '\n' << this->nspace_lc << service_name_lc << "_if_interface_init (" - << this->nspace << service_name_ << "IfInterface *iface)" << endl; + << this->nspace << service_name_ << "IfInterface *iface)" << '\n'; scope_up(f_service_); if (functions.size() > 0) { for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { @@ -1773,62 +1771,62 @@ void t_c_glib_generator::generate_service_client(t_service* tservice) { string funname = initial_caps_to_underscores((*f_iter)->get_name()); f_service_ << indent() << "iface->" << funname << " = " << this->nspace_lc - << service_name_lc << "_client_" << funname << ";" << endl; + << service_name_lc << "_client_" << funname << ";" << '\n'; } } else { - f_service_ << indent() << "THRIFT_UNUSED_VAR (iface);" << endl; + f_service_ << indent() << "THRIFT_UNUSED_VAR (iface);" << '\n'; } scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; // create the client instance initializer - f_service_ << "static void" << endl + f_service_ << "static void" << '\n' << this->nspace_lc << service_name_lc << "_client_init (" - << this->nspace << service_name_ << "Client *client)" << endl; + << this->nspace << service_name_ << "Client *client)" << '\n'; scope_up(f_service_); if (!extends_service) { - f_service_ << indent() << "client->input_protocol = NULL;" << endl - << indent() << "client->output_protocol = NULL;" << endl; + f_service_ << indent() << "client->input_protocol = NULL;" << '\n' + << indent() << "client->output_protocol = NULL;" << '\n'; } else { - f_service_ << indent() << "THRIFT_UNUSED_VAR (client);" << endl; + f_service_ << indent() << "THRIFT_UNUSED_VAR (client);" << '\n'; } scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; // create the client class initializer - f_service_ << "static void" << endl << this->nspace_lc << service_name_lc + f_service_ << "static void" << '\n' << this->nspace_lc << service_name_lc << "_client_class_init (" << this->nspace << service_name_ << "ClientClass *cls)" - << endl << "{" << endl; + << '\n' << "{" << '\n'; if (!extends_service) { - f_service_ << " GObjectClass *gobject_class = G_OBJECT_CLASS (cls);" << endl - << " GParamSpec *param_spec;" << endl << endl + f_service_ << " GObjectClass *gobject_class = G_OBJECT_CLASS (cls);" << '\n' + << " GParamSpec *param_spec;" << '\n' << '\n' << " gobject_class->set_property = " << this->nspace_lc << service_name_lc - << "_client_set_property;" << endl + << "_client_set_property;" << '\n' << " gobject_class->get_property = " << this->nspace_lc << service_name_lc - << "_client_get_property;" << endl << endl - << " param_spec = g_param_spec_object (\"input_protocol\"," << endl - << " \"input protocol (construct)\"," << endl - << " \"Set the client input protocol\"," << endl - << " THRIFT_TYPE_PROTOCOL," << endl - << " G_PARAM_READWRITE);" << endl - << " g_object_class_install_property (gobject_class," << endl + << "_client_get_property;" << '\n' << '\n' + << " param_spec = g_param_spec_object (\"input_protocol\"," << '\n' + << " \"input protocol (construct)\"," << '\n' + << " \"Set the client input protocol\"," << '\n' + << " THRIFT_TYPE_PROTOCOL," << '\n' + << " G_PARAM_READWRITE);" << '\n' + << " g_object_class_install_property (gobject_class," << '\n' << " PROP_" << this->nspace_uc << service_name_uc - << "_CLIENT_INPUT_PROTOCOL, param_spec);" << endl << endl - << " param_spec = g_param_spec_object (\"output_protocol\"," << endl - << " \"output protocol (construct)\"," << endl - << " \"Set the client output protocol\"," << endl - << " THRIFT_TYPE_PROTOCOL," << endl - << " G_PARAM_READWRITE);" << endl - << " g_object_class_install_property (gobject_class," << endl + << "_CLIENT_INPUT_PROTOCOL, param_spec);" << '\n' << '\n' + << " param_spec = g_param_spec_object (\"output_protocol\"," << '\n' + << " \"output protocol (construct)\"," << '\n' + << " \"Set the client output protocol\"," << '\n' + << " THRIFT_TYPE_PROTOCOL," << '\n' + << " G_PARAM_READWRITE);" << '\n' + << " g_object_class_install_property (gobject_class," << '\n' << " PROP_" << this->nspace_uc << service_name_uc - << "_CLIENT_OUTPUT_PROTOCOL, param_spec);" << endl; + << "_CLIENT_OUTPUT_PROTOCOL, param_spec);" << '\n'; } else { - f_service_ << " THRIFT_UNUSED_VAR (cls);" << endl; + f_service_ << " THRIFT_UNUSED_VAR (cls);" << '\n'; } - f_service_ << "}" << endl << endl; + f_service_ << "}" << '\n' << '\n'; } /** @@ -1874,19 +1872,19 @@ void t_c_glib_generator::generate_service_handler(t_service* tservice) { // Generate the handler class' definition in the header file // Generate the handler instance definition - f_header_ << "/* " << service_name_ << " handler (abstract base class) */" << endl << "struct _" - << class_name << endl << "{" << endl; + f_header_ << "/* " << service_name_ << " handler (abstract base class) */" << '\n' << "struct _" + << class_name << '\n' << "{" << '\n'; indent_up(); - f_header_ << indent() << parent_class_name << " parent;" << endl; + f_header_ << indent() << parent_class_name << " parent;" << '\n'; indent_down(); - f_header_ << "};" << endl << "typedef struct _" << class_name << " " << class_name << ";" << endl - << endl; + f_header_ << "};" << '\n' << "typedef struct _" << class_name << " " << class_name << ";" << '\n' + << '\n'; // Generate the handler class definition, including its class members // (methods) - f_header_ << "struct _" << class_name << "Class" << endl << "{" << endl; + f_header_ << "struct _" << class_name << "Class" << '\n' << "{" << '\n'; indent_up(); - f_header_ << indent() << parent_class_name << "Class parent;" << endl << endl; + f_header_ << indent() << parent_class_name << "Class parent;" << '\n' << '\n'; for (function_iter = functions.begin(); function_iter != functions.end(); ++function_iter) { string method_name = initial_caps_to_underscores((*function_iter)->get_name()); @@ -1902,31 +1900,31 @@ void t_c_glib_generator::generate_service_handler(t_service* tservice) { + (has_args ? "" : (", " + argument_list(arg_list))) + (has_xceptions ? "" : (", " + xception_list(x_list))) + ", GError **error)"; - indent(f_header_) << "gboolean (*" << method_name << ") " << params << ";" << endl; + indent(f_header_) << "gboolean (*" << method_name << ") " << params << ";" << '\n'; } indent_down(); - f_header_ << "};" << endl << "typedef struct _" << class_name << "Class " << class_name - << "Class;" << endl << endl; + f_header_ << "};" << '\n' << "typedef struct _" << class_name << "Class " << class_name + << "Class;" << '\n' << '\n'; // Generate the remaining header boilerplate - f_header_ << "GType " << class_name_lc << "_get_type (void);" << endl << "#define " + f_header_ << "GType " << class_name_lc << "_get_type (void);" << '\n' << "#define " << this->nspace_uc << "TYPE_" << service_name_uc << "_HANDLER " - << "(" << class_name_lc << "_get_type())" << endl << "#define " << class_name_uc + << "(" << class_name_lc << "_get_type())" << '\n' << "#define " << class_name_uc << "(obj) " << "(G_TYPE_CHECK_INSTANCE_CAST ((obj), " << this->nspace_uc << "TYPE_" - << service_name_uc << "_HANDLER, " << class_name << "))" << endl << "#define " + << service_name_uc << "_HANDLER, " << class_name << "))" << '\n' << "#define " << this->nspace_uc << "IS_" << service_name_uc << "_HANDLER(obj) " << "(G_TYPE_CHECK_INSTANCE_TYPE ((obj), " << this->nspace_uc << "TYPE_" - << service_name_uc << "_HANDLER))" << endl << "#define " << class_name_uc + << service_name_uc << "_HANDLER))" << '\n' << "#define " << class_name_uc << "_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), " << this->nspace_uc << "TYPE_" - << service_name_uc << "_HANDLER, " << class_name << "Class))" << endl << "#define " + << service_name_uc << "_HANDLER, " << class_name << "Class))" << '\n' << "#define " << this->nspace_uc << "IS_" << service_name_uc << "_HANDLER_CLASS(c) " << "(G_TYPE_CHECK_CLASS_TYPE ((c), " << this->nspace_uc << "TYPE_" << service_name_uc - << "_HANDLER))" << endl << "#define " << this->nspace_uc << service_name_uc + << "_HANDLER))" << '\n' << "#define " << this->nspace_uc << service_name_uc << "_HANDLER_GET_CLASS(obj) " << "(G_TYPE_INSTANCE_GET_CLASS ((obj), " << this->nspace_uc << "TYPE_" - << service_name_uc << "_HANDLER, " << class_name << "Class))" << endl << endl; + << service_name_uc << "_HANDLER, " << class_name << "Class))" << '\n' << '\n'; // Generate the handler class' method definitions for (function_iter = functions.begin(); function_iter != functions.end(); ++function_iter) { @@ -1943,25 +1941,25 @@ void t_c_glib_generator::generate_service_handler(t_service* tservice) { + (has_args ? "" : (", " + argument_list(arg_list))) + (has_xceptions ? "" : (", " + xception_list(x_list))) + ", GError **error)"; - f_header_ << "gboolean " << class_name_lc << "_" << method_name << " " << params << ";" << endl; + f_header_ << "gboolean " << class_name_lc << "_" << method_name << " " << params << ";" << '\n'; } - f_header_ << endl; + f_header_ << '\n'; // Generate the handler's implementation in the implementation file // Generate the implementation boilerplate - f_service_ << "static void" << endl << class_name_lc << "_" << service_name_lc + f_service_ << "static void" << '\n' << class_name_lc << "_" << service_name_lc << "_if_interface_init (" << this->nspace << service_name_ << "IfInterface *iface);" - << endl << endl; + << '\n' << '\n'; args_indent = string(25, ' '); - f_service_ << "G_DEFINE_TYPE_WITH_CODE (" << class_name << ", " << endl << args_indent - << class_name_lc << "," << endl << args_indent << parent_type_name << "," << endl + f_service_ << "G_DEFINE_TYPE_WITH_CODE (" << class_name << ", " << '\n' << args_indent + << class_name_lc << "," << '\n' << args_indent << parent_type_name << "," << '\n' << args_indent << "G_IMPLEMENT_INTERFACE (" << this->nspace_uc << "TYPE_" - << service_name_uc << "_IF," << endl; + << service_name_uc << "_IF," << '\n'; args_indent += string(23, ' '); f_service_ << args_indent << class_name_lc << "_" << service_name_lc << "_if_interface_init))" - << endl << endl; + << '\n' << '\n'; // Generate the handler method implementations for (function_iter = functions.begin(); function_iter != functions.end(); ++function_iter) { @@ -1982,10 +1980,10 @@ void t_c_glib_generator::generate_service_handler(t_service* tservice) { x_list, (*function_iter)->is_oneway()); - indent(f_service_) << function_signature(&implementing_function) << endl; + indent(f_service_) << function_signature(&implementing_function) << '\n'; scope_up(f_service_); f_service_ << indent() << "g_return_val_if_fail (" << this->nspace_uc << "IS_" - << service_name_uc << "_HANDLER (iface), FALSE);" << endl << endl << indent() + << service_name_uc << "_HANDLER (iface), FALSE);" << '\n' << '\n' << indent() << "return " << class_name_uc << "_GET_CLASS (iface)" << "->" << method_name << " (iface, "; @@ -1998,42 +1996,42 @@ void t_c_glib_generator::generate_service_handler(t_service* tservice) { for (field_iter = xceptions.begin(); field_iter != xceptions.end(); ++field_iter) { f_service_ << (*field_iter)->get_name() << ", "; } - f_service_ << "error);" << endl; + f_service_ << "error);" << '\n'; scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; } // Generate the handler interface initializer - f_service_ << "static void" << endl << class_name_lc << "_" << service_name_lc + f_service_ << "static void" << '\n' << class_name_lc << "_" << service_name_lc << "_if_interface_init (" << this->nspace << service_name_ << "IfInterface *iface)" - << endl; + << '\n'; scope_up(f_service_); if (functions.size() > 0) { for (function_iter = functions.begin(); function_iter != functions.end(); ++function_iter) { string method_name = initial_caps_to_underscores((*function_iter)->get_name()); f_service_ << indent() << "iface->" << method_name << " = " << class_name_lc << "_" - << method_name << ";" << endl; + << method_name << ";" << '\n'; } } else { - f_service_ << "THRIFT_UNUSED_VAR (iface);" << endl; + f_service_ << "THRIFT_UNUSED_VAR (iface);" << '\n'; } scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; // Generate the handler instance initializer - f_service_ << "static void" << endl << class_name_lc << "_init (" << class_name << " *self)" - << endl; + f_service_ << "static void" << '\n' << class_name_lc << "_init (" << class_name << " *self)" + << '\n'; scope_up(f_service_); - f_service_ << indent() << "THRIFT_UNUSED_VAR (self);" << endl; + f_service_ << indent() << "THRIFT_UNUSED_VAR (self);" << '\n'; scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; // Generate the handler class initializer - f_service_ << "static void" << endl + f_service_ << "static void" << '\n' << class_name_lc << "_class_init (" << class_name << "Class *cls)" - << endl; + << '\n'; scope_up(f_service_); if (functions.size() > 0) { for (function_iter = functions.begin(); @@ -2043,14 +2041,14 @@ void t_c_glib_generator::generate_service_handler(t_service* tservice) { string method_name = initial_caps_to_underscores(function_name); // All methods are pure virtual and must be implemented by subclasses - f_service_ << indent() << "cls->" << method_name << " = NULL;" << endl; + f_service_ << indent() << "cls->" << method_name << " = NULL;" << '\n'; } } else { - f_service_ << indent() << "THRIFT_UNUSED_VAR (cls);" << endl; + f_service_ << indent() << "THRIFT_UNUSED_VAR (cls);" << '\n'; } scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; } /** @@ -2104,84 +2102,84 @@ void t_c_glib_generator::generate_service_processor(t_service* tservice) { // Generate the processor class' definition in the header file // Generate the processor instance definition - f_header_ << "/* " << service_name_ << " processor */" << endl << "struct _" << class_name << endl - << "{" << endl; + f_header_ << "/* " << service_name_ << " processor */" << '\n' << "struct _" << class_name << '\n' + << "{" << '\n'; indent_up(); - f_header_ << indent() << parent_class_name << " parent;" << endl << endl << indent() - << "/* protected */" << endl << indent() - << this->nspace + service_name_ + "Handler *handler;" << endl << indent() - << "GHashTable *process_map;" << endl; + f_header_ << indent() << parent_class_name << " parent;" << '\n' << '\n' << indent() + << "/* protected */" << '\n' << indent() + << this->nspace + service_name_ + "Handler *handler;" << '\n' << indent() + << "GHashTable *process_map;" << '\n'; indent_down(); - f_header_ << "};" << endl << "typedef struct _" << class_name << " " << class_name << ";" << endl - << endl; + f_header_ << "};" << '\n' << "typedef struct _" << class_name << " " << class_name << ";" << '\n' + << '\n'; // Generate the processor class definition - f_header_ << "struct _" << class_name << "Class" << endl << "{" << endl; + f_header_ << "struct _" << class_name << "Class" << '\n' << "{" << '\n'; indent_up(); - f_header_ << indent() << parent_class_name << "Class parent;" << endl << endl << indent() - << "/* protected */" << endl << indent() - << "gboolean (*dispatch_call) (ThriftDispatchProcessor *processor," << endl; + f_header_ << indent() << parent_class_name << "Class parent;" << '\n' << '\n' << indent() + << "/* protected */" << '\n' << indent() + << "gboolean (*dispatch_call) (ThriftDispatchProcessor *processor," << '\n'; args_indent = indent() + string(27, ' '); - f_header_ << args_indent << "ThriftProtocol *in," << endl << args_indent << "ThriftProtocol *out," - << endl << args_indent << "gchar *fname," << endl << args_indent << "gint32 seqid," - << endl << args_indent << "GError **error);" << endl; + f_header_ << args_indent << "ThriftProtocol *in," << '\n' << args_indent << "ThriftProtocol *out," + << '\n' << args_indent << "gchar *fname," << '\n' << args_indent << "gint32 seqid," + << '\n' << args_indent << "GError **error);" << '\n'; indent_down(); - f_header_ << "};" << endl << "typedef struct _" << class_name << "Class " << class_name - << "Class;" << endl << endl; + f_header_ << "};" << '\n' << "typedef struct _" << class_name << "Class " << class_name + << "Class;" << '\n' << '\n'; // Generate the remaining header boilerplate - f_header_ << "GType " << class_name_lc << "_get_type (void);" << endl << "#define " + f_header_ << "GType " << class_name_lc << "_get_type (void);" << '\n' << "#define " << this->nspace_uc << "TYPE_" << service_name_uc << "_PROCESSOR " - << "(" << class_name_lc << "_get_type())" << endl << "#define " << class_name_uc + << "(" << class_name_lc << "_get_type())" << '\n' << "#define " << class_name_uc << "(obj) " << "(G_TYPE_CHECK_INSTANCE_CAST ((obj), " << this->nspace_uc << "TYPE_" - << service_name_uc << "_PROCESSOR, " << class_name << "))" << endl << "#define " + << service_name_uc << "_PROCESSOR, " << class_name << "))" << '\n' << "#define " << this->nspace_uc << "IS_" << service_name_uc << "_PROCESSOR(obj) " << "(G_TYPE_CHECK_INSTANCE_TYPE ((obj), " << this->nspace_uc << "TYPE_" - << service_name_uc << "_PROCESSOR))" << endl << "#define " << class_name_uc + << service_name_uc << "_PROCESSOR))" << '\n' << "#define " << class_name_uc << "_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), " << this->nspace_uc << "TYPE_" - << service_name_uc << "_PROCESSOR, " << class_name << "Class))" << endl << "#define " + << service_name_uc << "_PROCESSOR, " << class_name << "Class))" << '\n' << "#define " << this->nspace_uc << "IS_" << service_name_uc << "_PROCESSOR_CLASS(c) " << "(G_TYPE_CHECK_CLASS_TYPE ((c), " << this->nspace_uc << "TYPE_" << service_name_uc - << "_PROCESSOR))" << endl << "#define " << this->nspace_uc << service_name_uc + << "_PROCESSOR))" << '\n' << "#define " << this->nspace_uc << service_name_uc << "_PROCESSOR_GET_CLASS(obj) " << "(G_TYPE_INSTANCE_GET_CLASS ((obj), " << this->nspace_uc << "TYPE_" - << service_name_uc << "_PROCESSOR, " << class_name << "Class))" << endl << endl; + << service_name_uc << "_PROCESSOR, " << class_name << "Class))" << '\n' << '\n'; // Generate the processor's implementation in the implementation file // Generate the processor's properties enum - f_service_ << "enum _" << class_name << "Properties" << endl << "{" << endl; + f_service_ << "enum _" << class_name << "Properties" << '\n' << "{" << '\n'; indent_up(); - f_service_ << indent() << "PROP_" << class_name_uc << "_0," << endl << indent() << "PROP_" - << class_name_uc << "_HANDLER" << endl; + f_service_ << indent() << "PROP_" << class_name_uc << "_0," << '\n' << indent() << "PROP_" + << class_name_uc << "_HANDLER" << '\n'; indent_down(); - f_service_ << "};" << endl << endl; + f_service_ << "};" << '\n' << '\n'; // Generate the implementation boilerplate args_indent = string(15, ' '); - f_service_ << "G_DEFINE_TYPE (" << class_name << "," << endl << args_indent << class_name_lc - << "," << endl << args_indent << parent_type_name << ")" << endl << endl; + f_service_ << "G_DEFINE_TYPE (" << class_name << "," << '\n' << args_indent << class_name_lc + << "," << '\n' << args_indent << parent_type_name << ")" << '\n' << '\n'; // Generate the processor's processing-function type args_indent = string(process_function_type_name.length() + 23, ' '); f_service_ << "typedef gboolean (* " << process_function_type_name << ") (" - << class_name << " *, " << endl - << args_indent << "gint32," << endl - << args_indent << "ThriftProtocol *," << endl - << args_indent << "ThriftProtocol *," << endl - << args_indent << "GError **);" << endl - << endl; + << class_name << " *, " << '\n' + << args_indent << "gint32," << '\n' + << args_indent << "ThriftProtocol *," << '\n' + << args_indent << "ThriftProtocol *," << '\n' + << args_indent << "GError **);" << '\n' + << '\n'; // Generate the processor's processing-function-definition type - f_service_ << "typedef struct" << endl - << "{" << endl; + f_service_ << "typedef struct" << '\n' + << "{" << '\n'; indent_up(); - f_service_ << indent() << "gchar *name;" << endl - << indent() << process_function_type_name << " function;" << endl; + f_service_ << indent() << "gchar *name;" << '\n' + << indent() << process_function_type_name << " function;" << '\n'; indent_down(); - f_service_ << "} " << process_function_def_type_name << ";" << endl - << endl; + f_service_ << "} " << process_function_def_type_name << ";" << '\n' + << '\n'; // Generate forward declarations of the processor's processing functions so we // can refer to them in the processing-function-definition struct below and @@ -2193,23 +2191,23 @@ void t_c_glib_generator::generate_service_processor(t_service* tservice) { + initial_caps_to_underscores((*function_iter)->get_name()); args_indent = string(function_name.length() + 2, ' '); - f_service_ << "static gboolean" << endl + f_service_ << "static gboolean" << '\n' << function_name << " (" - << class_name << " *," << endl - << args_indent << "gint32," << endl - << args_indent << "ThriftProtocol *," << endl - << args_indent << "ThriftProtocol *," << endl - << args_indent << "GError **);" << endl; + << class_name << " *," << '\n' + << args_indent << "gint32," << '\n' + << args_indent << "ThriftProtocol *," << '\n' + << args_indent << "ThriftProtocol *," << '\n' + << args_indent << "GError **);" << '\n'; } - f_service_ << endl; + f_service_ << '\n'; // Generate the processor's processing-function definitions, if the service // defines any methods if (functions.size() > 0) { f_service_ << indent() << "static " << process_function_def_type_name - << endl + << '\n' << indent() << class_name_lc << "_process_function_defs[" - << functions.size() << "] = {" << endl; + << functions.size() << "] = {" << '\n'; indent_up(); for (function_iter = functions.begin(); function_iter != functions.end(); @@ -2218,17 +2216,17 @@ void t_c_glib_generator::generate_service_processor(t_service* tservice) { string process_function_name = class_name_lc + "_process_" + initial_caps_to_underscores(service_function_name); - f_service_ << indent() << "{" << endl; + f_service_ << indent() << "{" << '\n'; indent_up(); - f_service_ << indent() << "\"" << service_function_name << "\"," << endl - << indent() << process_function_name << endl; + f_service_ << indent() << "\"" << service_function_name << "\"," << '\n' + << indent() << process_function_name << '\n'; indent_down(); f_service_ << indent() << "}" - << (function_iter == --functions.end() ? "" : ",") << endl; + << (function_iter == --functions.end() ? "" : ",") << '\n'; } indent_down(); - f_service_ << indent() << "};" << endl - << endl; + f_service_ << indent() << "};" << '\n' + << '\n'; } // Generate the processor's processing functions @@ -2262,76 +2260,76 @@ void t_c_glib_generator::generate_service_processor(t_service* tservice) { + initial_caps_to_underscores(service_function_name); args_indent = string(function_name.length() + 2, ' '); - f_service_ << "static gboolean" << endl << function_name << " (" << class_name << " *self," - << endl << args_indent << "gint32 sequence_id," << endl << args_indent - << "ThriftProtocol *input_protocol," << endl << args_indent - << "ThriftProtocol *output_protocol," << endl << args_indent << "GError **error)" - << endl; + f_service_ << "static gboolean" << '\n' << function_name << " (" << class_name << " *self," + << '\n' << args_indent << "gint32 sequence_id," << '\n' << args_indent + << "ThriftProtocol *input_protocol," << '\n' << args_indent + << "ThriftProtocol *output_protocol," << '\n' << args_indent << "GError **error)" + << '\n'; scope_up(f_service_); - f_service_ << indent() << "gboolean result = TRUE;" << endl - << indent() << "ThriftTransport * transport;" << endl - << indent() << "ThriftApplicationException *xception;" << endl - << indent() << args_class_name + " * args =" << endl; + f_service_ << indent() << "gboolean result = TRUE;" << '\n' + << indent() << "ThriftTransport * transport;" << '\n' + << indent() << "ThriftApplicationException *xception;" << '\n' + << indent() << args_class_name + " * args =" << '\n'; indent_up(); - f_service_ << indent() << "g_object_new (" << args_class_type << ", NULL);" << endl << endl; + f_service_ << indent() << "g_object_new (" << args_class_type << ", NULL);" << '\n' << '\n'; indent_down(); if ((*function_iter)->is_oneway()) { - f_service_ << indent() << "THRIFT_UNUSED_VAR (sequence_id);" << endl << indent() - << "THRIFT_UNUSED_VAR (output_protocol);" << endl << endl; + f_service_ << indent() << "THRIFT_UNUSED_VAR (sequence_id);" << '\n' << indent() + << "THRIFT_UNUSED_VAR (output_protocol);" << '\n' << '\n'; } f_service_ << indent() << "g_object_get (input_protocol, \"transport\", " - << "&transport, NULL);" << endl << endl; + << "&transport, NULL);" << '\n' << '\n'; // Read the method's arguments from the caller f_service_ << indent() << "if ((thrift_struct_read (THRIFT_STRUCT (args), " - << "input_protocol, error) != -1) &&" << endl << indent() + << "input_protocol, error) != -1) &&" << '\n' << indent() << " (thrift_protocol_read_message_end (input_protocol, " - << "error) != -1) &&" << endl << indent() - << " (thrift_transport_read_end (transport, error) != FALSE))" << endl; + << "error) != -1) &&" << '\n' << indent() + << " (thrift_transport_read_end (transport, error) != FALSE))" << '\n'; scope_up(f_service_); for (arg_iter = args.begin(); arg_iter != args.end(); ++arg_iter) { f_service_ << indent() << property_type_name((*arg_iter)->get_type()) << " " - << (*arg_iter)->get_name() << ";" << endl; + << (*arg_iter)->get_name() << ";" << '\n'; } for (xception_iter = xceptions.begin(); xception_iter != xceptions.end(); ++xception_iter) { f_service_ << indent() << type_name((*xception_iter)->get_type()) << " " - << initial_caps_to_underscores((*xception_iter)->get_name()) << " = NULL;" << endl; + << initial_caps_to_underscores((*xception_iter)->get_name()) << " = NULL;" << '\n'; } if (has_return_value) { - f_service_ << indent() << property_type_name(return_type) << " return_value;" << endl; + f_service_ << indent() << property_type_name(return_type) << " return_value;" << '\n'; } if (!(*function_iter)->is_oneway()) { - f_service_ << indent() << result_class_name << " * result_struct;" << endl; + f_service_ << indent() << result_class_name << " * result_struct;" << '\n'; } - f_service_ << endl; + f_service_ << '\n'; if (args.size() > 0) { - f_service_ << indent() << "g_object_get (args," << endl; + f_service_ << indent() << "g_object_get (args," << '\n'; args_indent = indent() + string(14, ' '); for (arg_iter = args.begin(); arg_iter != args.end(); ++arg_iter) { string arg_name = (*arg_iter)->get_name(); - f_service_ << args_indent << "\"" << arg_name << "\", &" << arg_name << "," << endl; + f_service_ << args_indent << "\"" << arg_name << "\", &" << arg_name << "," << '\n'; } - f_service_ << args_indent << "NULL);" << endl << endl; + f_service_ << args_indent << "NULL);" << '\n' << '\n'; } if (!(*function_iter)->is_oneway()) { - f_service_ << indent() << "g_object_unref (transport);" << endl << indent() + f_service_ << indent() << "g_object_unref (transport);" << '\n' << indent() << "g_object_get (output_protocol, \"transport\", " - << "&transport, NULL);" << endl << endl << indent() - << "result_struct = g_object_new (" << result_class_type << ", NULL);" << endl; + << "&transport, NULL);" << '\n' << '\n' << indent() + << "result_struct = g_object_new (" << result_class_type << ", NULL);" << '\n'; if (has_return_value) { f_service_ << indent() << "g_object_get (result_struct, " - "\"success\", &return_value, NULL);" << endl; + "\"success\", &return_value, NULL);" << '\n'; } - f_service_ << endl; + f_service_ << '\n'; } // Pass the arguments to the corresponding method in the handler f_service_ << indent() << "if (" << handler_function_name << " (" << this->nspace_uc - << service_name_uc << "_IF (self->handler)," << endl; + << service_name_uc << "_IF (self->handler)," << '\n'; args_indent = indent() + string(handler_function_name.length() + 6, ' '); if (has_return_value) { string return_type_name = type_name(return_type); @@ -2351,16 +2349,16 @@ void t_c_glib_generator::generate_service_processor(t_service* tservice) { f_service_ << "(" << return_type_name << ")"; } - f_service_ << "&return_value," << endl; + f_service_ << "&return_value," << '\n'; } for (arg_iter = args.begin(); arg_iter != args.end(); ++arg_iter) { - f_service_ << args_indent << (*arg_iter)->get_name() << "," << endl; + f_service_ << args_indent << (*arg_iter)->get_name() << "," << '\n'; } for (xception_iter = xceptions.begin(); xception_iter != xceptions.end(); ++xception_iter) { f_service_ << args_indent << "&" << initial_caps_to_underscores((*xception_iter)->get_name()) - << "," << endl; + << "," << '\n'; } - f_service_ << args_indent << "error) == TRUE)" << endl; + f_service_ << args_indent << "error) == TRUE)" << '\n'; scope_up(f_service_); // The handler reported success; return the result, if any, to the caller @@ -2373,24 +2371,24 @@ void t_c_glib_generator::generate_service_processor(t_service* tservice) { << "(" << type_name(return_type) << ")"; } f_service_ << "return_value, " - << "NULL);" << endl; - f_service_ << endl; + << "NULL);" << '\n'; + f_service_ << '\n'; } - f_service_ << indent() << "result =" << endl; + f_service_ << indent() << "result =" << '\n'; indent_up(); - f_service_ << indent() << "((thrift_protocol_write_message_begin (output_protocol," << endl; + f_service_ << indent() << "((thrift_protocol_write_message_begin (output_protocol," << '\n'; args_indent = indent() + string(39, ' '); - f_service_ << args_indent << "\"" << service_function_name << "\"," << endl << args_indent - << "T_REPLY," << endl << args_indent << "sequence_id," << endl << args_indent - << "error) != -1) &&" << endl << indent() - << " (thrift_struct_write (THRIFT_STRUCT (result_struct)," << endl; + f_service_ << args_indent << "\"" << service_function_name << "\"," << '\n' << args_indent + << "T_REPLY," << '\n' << args_indent << "sequence_id," << '\n' << args_indent + << "error) != -1) &&" << '\n' << indent() + << " (thrift_struct_write (THRIFT_STRUCT (result_struct)," << '\n'; args_indent = indent() + string(23, ' '); - f_service_ << args_indent << "output_protocol," << endl << args_indent << "error) != -1));" - << endl; + f_service_ << args_indent << "output_protocol," << '\n' << args_indent << "error) != -1));" + << '\n'; indent_down(); } scope_down(f_service_); - f_service_ << indent() << "else" << endl; + f_service_ << indent() << "else" << '\n'; scope_up(f_service_); // The handler reported failure; check to see if an application-defined @@ -2399,28 +2397,28 @@ void t_c_glib_generator::generate_service_processor(t_service* tservice) { if (xceptions.size() > 0) { for (xception_iter = xceptions.begin(); xception_iter != xceptions.end(); ++xception_iter) { f_service_ << "if (" << initial_caps_to_underscores((*xception_iter)->get_name()) - << " != NULL)" << endl; + << " != NULL)" << '\n'; scope_up(f_service_); - f_service_ << indent() << "g_object_set (result_struct," << endl; + f_service_ << indent() << "g_object_set (result_struct," << '\n'; args_indent = indent() + string(14, ' '); f_service_ << args_indent << "\"" << (*xception_iter)->get_name() << "\", " - << (*xception_iter)->get_name() << "," << endl << args_indent << "NULL);" << endl - << endl; - f_service_ << indent() << "g_object_unref ("<< (*xception_iter)->get_name() <<");"<< endl; - f_service_ << indent() << "result =" << endl; + << (*xception_iter)->get_name() << "," << '\n' << args_indent << "NULL);" << '\n' + << '\n'; + f_service_ << indent() << "g_object_unref ("<< (*xception_iter)->get_name() <<");"<< '\n'; + f_service_ << indent() << "result =" << '\n'; indent_up(); - f_service_ << indent() << "((thrift_protocol_write_message_begin (output_protocol," << endl; + f_service_ << indent() << "((thrift_protocol_write_message_begin (output_protocol," << '\n'; args_indent = indent() + string(39, ' '); - f_service_ << args_indent << "\"" << service_function_name << "\"," << endl << args_indent - << "T_REPLY," << endl << args_indent << "sequence_id," << endl << args_indent - << "error) != -1) &&" << endl << indent() - << " (thrift_struct_write (THRIFT_STRUCT (result_struct)," << endl; + f_service_ << args_indent << "\"" << service_function_name << "\"," << '\n' << args_indent + << "T_REPLY," << '\n' << args_indent << "sequence_id," << '\n' << args_indent + << "error) != -1) &&" << '\n' << indent() + << " (thrift_struct_write (THRIFT_STRUCT (result_struct)," << '\n'; args_indent = indent() + string(23, ' '); - f_service_ << args_indent << "output_protocol," << endl << args_indent << "error) != -1));" - << endl; + f_service_ << args_indent << "output_protocol," << '\n' << args_indent << "error) != -1));" + << '\n'; indent_down(); scope_down(f_service_); - f_service_ << indent() << "else" << endl; + f_service_ << indent() << "else" << '\n'; } scope_up(f_service_); @@ -2430,41 +2428,41 @@ void t_c_glib_generator::generate_service_processor(t_service* tservice) { // If the handler reported failure but raised no application-defined // exception, return a Thrift application exception with the information // returned via GLib's own error-reporting mechanism - f_service_ << "if (*error == NULL)" << endl; + f_service_ << "if (*error == NULL)" << '\n'; indent_up(); f_service_ << indent() << "g_warning (\"" << service_name_ << "." - << (*function_iter)->get_name() << " implementation returned FALSE \"" << endl - << indent() << string(11, ' ') << "\"but did not set an error\");" << endl << endl; + << (*function_iter)->get_name() << " implementation returned FALSE \"" << '\n' + << indent() << string(11, ' ') << "\"but did not set an error\");" << '\n' << '\n'; indent_down(); - f_service_ << indent() << "xception =" << endl; + f_service_ << indent() << "xception =" << '\n'; indent_up(); - f_service_ << indent() << "g_object_new (THRIFT_TYPE_APPLICATION_EXCEPTION," << endl; + f_service_ << indent() << "g_object_new (THRIFT_TYPE_APPLICATION_EXCEPTION," << '\n'; args_indent = indent() + string(14, ' '); - f_service_ << args_indent << "\"type\", *error != NULL ? (*error)->code :" << endl + f_service_ << args_indent << "\"type\", *error != NULL ? (*error)->code :" << '\n' << args_indent << string(11, ' ') << "THRIFT_APPLICATION_EXCEPTION_ERROR_UNKNOWN," - << endl << args_indent << "\"message\", *error != NULL ? (*error)->message : NULL," - << endl << args_indent << "NULL);" << endl; + << '\n' << args_indent << "\"message\", *error != NULL ? (*error)->message : NULL," + << '\n' << args_indent << "NULL);" << '\n'; indent_down(); - f_service_ << indent() << "g_clear_error (error);" << endl << endl << indent() - << "result =" << endl; + f_service_ << indent() << "g_clear_error (error);" << '\n' << '\n' << indent() + << "result =" << '\n'; indent_up(); - f_service_ << indent() << "((thrift_protocol_write_message_begin (output_protocol," << endl; + f_service_ << indent() << "((thrift_protocol_write_message_begin (output_protocol," << '\n'; args_indent = indent() + string(39, ' '); - f_service_ << args_indent << "\"" << service_function_name << "\"," << endl << args_indent - << "T_EXCEPTION," << endl << args_indent << "sequence_id," << endl << args_indent - << "error) != -1) &&" << endl << indent() - << " (thrift_struct_write (THRIFT_STRUCT (xception)," << endl; + f_service_ << args_indent << "\"" << service_function_name << "\"," << '\n' << args_indent + << "T_EXCEPTION," << '\n' << args_indent << "sequence_id," << '\n' << args_indent + << "error) != -1) &&" << '\n' << indent() + << " (thrift_struct_write (THRIFT_STRUCT (xception)," << '\n'; args_indent = indent() + string(23, ' '); - f_service_ << args_indent << "output_protocol," << endl << args_indent << "error) != -1));" - << endl; + f_service_ << args_indent << "output_protocol," << '\n' << args_indent << "error) != -1));" + << '\n'; indent_down(); - f_service_ << endl << indent() << "g_object_unref (xception);" << endl; + f_service_ << '\n' << indent() << "g_object_unref (xception);" << '\n'; if (xceptions.size() > 0) { scope_down(f_service_); } scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; // Dellocate or unref retrieved argument values as necessary for (arg_iter = args.begin(); arg_iter != args.end(); ++arg_iter) { @@ -2475,17 +2473,17 @@ void t_c_glib_generator::generate_service_processor(t_service* tservice) { t_base_type* base_type = ((t_base_type*)arg_type); if (base_type->get_base() == t_base_type::TYPE_STRING) { - f_service_ << indent() << "if (" << arg_name << " != NULL)" << endl; + f_service_ << indent() << "if (" << arg_name << " != NULL)" << '\n'; indent_up(); if (base_type->is_binary()) { - f_service_ << indent() << "g_byte_array_unref (" << arg_name << ");" << endl; + f_service_ << indent() << "g_byte_array_unref (" << arg_name << ");" << '\n'; } else { - f_service_ << indent() << "g_free (" << arg_name << ");" << endl; + f_service_ << indent() << "g_free (" << arg_name << ");" << '\n'; } indent_down(); } } else if (arg_type->is_container()) { - f_service_ << indent() << "if (" << arg_name << " != NULL)" << endl; + f_service_ << indent() << "if (" << arg_name << " != NULL)" << '\n'; indent_up(); if (arg_type->is_list()) { @@ -2497,16 +2495,16 @@ void t_c_glib_generator::generate_service_processor(t_service* tservice) { } else { f_service_ << "g_ptr_array_unref"; } - f_service_ << " (" << arg_name << ");" << endl; + f_service_ << " (" << arg_name << ");" << '\n'; } else if (arg_type->is_map() || arg_type->is_set()) { - f_service_ << indent() << "g_hash_table_unref (" << arg_name << ");" << endl; + f_service_ << indent() << "g_hash_table_unref (" << arg_name << ");" << '\n'; } indent_down(); } else if (arg_type->is_struct()) { - f_service_ << indent() << "if (" << arg_name << " != NULL)" << endl; + f_service_ << indent() << "if (" << arg_name << " != NULL)" << '\n'; indent_up(); - f_service_ << indent() << "g_object_unref (" << arg_name << ");" << endl; + f_service_ << indent() << "g_object_unref (" << arg_name << ");" << '\n'; indent_down(); } } @@ -2518,17 +2516,17 @@ void t_c_glib_generator::generate_service_processor(t_service* tservice) { if (return_type->is_base_type()) { t_base_type* base_type = ((t_base_type*)return_type); if (base_type->get_base() == t_base_type::TYPE_STRING) { - f_service_ << indent() << "if (return_value != NULL)" << endl; + f_service_ << indent() << "if (return_value != NULL)" << '\n'; indent_up(); if (base_type->is_binary()) { - f_service_ << indent() << "g_byte_array_unref (return_value);" << endl; + f_service_ << indent() << "g_byte_array_unref (return_value);" << '\n'; } else { - f_service_ << indent() << "g_free (return_value);" << endl; + f_service_ << indent() << "g_free (return_value);" << '\n'; } indent_down(); } } else if (return_type->is_container()) { - f_service_ << indent() << "if (return_value != NULL)" << endl; + f_service_ << indent() << "if (return_value != NULL)" << '\n'; indent_up(); if (return_type->is_list()) { @@ -2540,81 +2538,81 @@ void t_c_glib_generator::generate_service_processor(t_service* tservice) { } else { f_service_ << "g_ptr_array_unref"; } - f_service_ << " (return_value);" << endl; + f_service_ << " (return_value);" << '\n'; } else if (return_type->is_map() || return_type->is_set()) { - f_service_ << indent() << "g_hash_table_unref (return_value);" << endl; + f_service_ << indent() << "g_hash_table_unref (return_value);" << '\n'; } indent_down(); } else if (return_type->is_struct()) { - f_service_ << indent() << "if (return_value != NULL)" << endl; + f_service_ << indent() << "if (return_value != NULL)" << '\n'; indent_up(); - f_service_ << indent() << "g_object_unref (return_value);" << endl; + f_service_ << indent() << "g_object_unref (return_value);" << '\n'; indent_down(); } } - f_service_ << indent() << "g_object_unref (result_struct);" << endl << endl << indent() - << "if (result == TRUE)" << endl; + f_service_ << indent() << "g_object_unref (result_struct);" << '\n' << '\n' << indent() + << "if (result == TRUE)" << '\n'; indent_up(); - f_service_ << indent() << "result =" << endl; + f_service_ << indent() << "result =" << '\n'; indent_up(); f_service_ << indent() << "((thrift_protocol_write_message_end " - << "(output_protocol, error) != -1) &&" << endl << indent() + << "(output_protocol, error) != -1) &&" << '\n' << indent() << " (thrift_transport_write_end (transport, error) " - << "!= FALSE) &&" << endl << indent() + << "!= FALSE) &&" << '\n' << indent() << " (thrift_transport_flush (transport, error) " - << "!= FALSE));" << endl; + << "!= FALSE));" << '\n'; indent_down(); indent_down(); } scope_down(f_service_); - f_service_ << indent() << "else" << endl; + f_service_ << indent() << "else" << '\n'; indent_up(); - f_service_ << indent() << "result = FALSE;" << endl; + f_service_ << indent() << "result = FALSE;" << '\n'; indent_down(); - f_service_ << endl << indent() << "g_object_unref (transport);" << endl << indent() - << "g_object_unref (args);" << endl << endl << indent() << "return result;" << endl; + f_service_ << '\n' << indent() << "g_object_unref (transport);" << '\n' << indent() + << "g_object_unref (args);" << '\n' << '\n' << indent() << "return result;" << '\n'; scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; } // Generate the processor's dispatch_call implementation function_name = class_name_lc + "_dispatch_call"; args_indent = indent() + string(function_name.length() + 2, ' '); - f_service_ << "static gboolean" << endl << function_name - << " (ThriftDispatchProcessor *dispatch_processor," << endl << args_indent - << "ThriftProtocol *input_protocol," << endl << args_indent - << "ThriftProtocol *output_protocol," << endl << args_indent << "gchar *method_name," - << endl << args_indent << "gint32 sequence_id," << endl << args_indent - << "GError **error)" << endl; + f_service_ << "static gboolean" << '\n' << function_name + << " (ThriftDispatchProcessor *dispatch_processor," << '\n' << args_indent + << "ThriftProtocol *input_protocol," << '\n' << args_indent + << "ThriftProtocol *output_protocol," << '\n' << args_indent << "gchar *method_name," + << '\n' << args_indent << "gint32 sequence_id," << '\n' << args_indent + << "GError **error)" << '\n'; scope_up(f_service_); f_service_ << indent() << class_name_lc << "_process_function_def *" - << "process_function_def;" << endl; - f_service_ << indent() << "gboolean dispatch_result = FALSE;" << endl << endl << indent() - << class_name << " *self = " << class_name_uc << " (dispatch_processor);" << endl; + << "process_function_def;" << '\n'; + f_service_ << indent() << "gboolean dispatch_result = FALSE;" << '\n' << '\n' << indent() + << class_name << " *self = " << class_name_uc << " (dispatch_processor);" << '\n'; f_service_ << indent() << parent_class_name << "Class " - "*parent_class =" << endl; + "*parent_class =" << '\n'; indent_up(); f_service_ << indent() << "g_type_class_peek_parent (" << class_name_uc << "_GET_CLASS (self));" - << endl; + << '\n'; indent_down(); - f_service_ << endl + f_service_ << '\n' << indent() << "process_function_def = " - << "g_hash_table_lookup (self->process_map, method_name);" << endl - << indent() << "if (process_function_def != NULL)" << endl; + << "g_hash_table_lookup (self->process_map, method_name);" << '\n' + << indent() << "if (process_function_def != NULL)" << '\n'; scope_up(f_service_); args_indent = indent() + string(53, ' '); - f_service_ << indent() << "g_free (method_name);" << endl + f_service_ << indent() << "g_free (method_name);" << '\n' << indent() << "dispatch_result = " - << "(*process_function_def->function) (self," << endl - << args_indent << "sequence_id," << endl - << args_indent << "input_protocol," << endl - << args_indent << "output_protocol," << endl - << args_indent << "error);" << endl; + << "(*process_function_def->function) (self," << '\n' + << args_indent << "sequence_id," << '\n' + << args_indent << "input_protocol," << '\n' + << args_indent << "output_protocol," << '\n' + << args_indent << "error);" << '\n'; scope_down(f_service_); - f_service_ << indent() << "else" << endl; + f_service_ << indent() << "else" << '\n'; scope_up(f_service_); // Method name not recognized; chain up to our parent processor---note the @@ -2622,160 +2620,160 @@ void t_c_glib_generator::generate_service_processor(t_service* tservice) { // will return an application exception to the caller if no class in the // hierarchy recognizes the method name f_service_ << indent() << "dispatch_result = parent_class->dispatch_call " - "(dispatch_processor," << endl; + "(dispatch_processor," << '\n'; args_indent = indent() + string(47, ' '); - f_service_ << args_indent << "input_protocol," << endl << args_indent << "output_protocol," - << endl << args_indent << "method_name," << endl << args_indent << "sequence_id," - << endl << args_indent << "error);" << endl; + f_service_ << args_indent << "input_protocol," << '\n' << args_indent << "output_protocol," + << '\n' << args_indent << "method_name," << '\n' << args_indent << "sequence_id," + << '\n' << args_indent << "error);" << '\n'; scope_down(f_service_); - f_service_ << endl << indent() << "return dispatch_result;" << endl; + f_service_ << '\n' << indent() << "return dispatch_result;" << '\n'; scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; // Generate the processor's property setter function_name = class_name_lc + "_set_property"; args_indent = string(function_name.length() + 2, ' '); - f_service_ << "static void" << endl << function_name << " (GObject *object," << endl - << args_indent << "guint property_id," << endl << args_indent << "const GValue *value," - << endl << args_indent << "GParamSpec *pspec)" << endl; + f_service_ << "static void" << '\n' << function_name << " (GObject *object," << '\n' + << args_indent << "guint property_id," << '\n' << args_indent << "const GValue *value," + << '\n' << args_indent << "GParamSpec *pspec)" << '\n'; scope_up(f_service_); - f_service_ << indent() << class_name << " *self = " << class_name_uc << " (object);" << endl - << endl << indent() << "switch (property_id)" << endl; + f_service_ << indent() << class_name << " *self = " << class_name_uc << " (object);" << '\n' + << '\n' << indent() << "switch (property_id)" << '\n'; scope_up(f_service_); - f_service_ << indent() << "case PROP_" << class_name_uc << "_HANDLER:" << endl; + f_service_ << indent() << "case PROP_" << class_name_uc << "_HANDLER:" << '\n'; indent_up(); - f_service_ << indent() << "if (self->handler != NULL)" << endl; + f_service_ << indent() << "if (self->handler != NULL)" << '\n'; indent_up(); - f_service_ << indent() << "g_object_unref (self->handler);" << endl; + f_service_ << indent() << "g_object_unref (self->handler);" << '\n'; indent_down(); - f_service_ << indent() << "self->handler = g_value_get_object (value);" << endl << indent() - << "g_object_ref (self->handler);" << endl; + f_service_ << indent() << "self->handler = g_value_get_object (value);" << '\n' << indent() + << "g_object_ref (self->handler);" << '\n'; if (extends_service) { // Chain up to set the handler in every superclass as well - f_service_ << endl << indent() << "G_OBJECT_CLASS (" << class_name_lc << "_parent_class)->" - << endl; + f_service_ << '\n' << indent() << "G_OBJECT_CLASS (" << class_name_lc << "_parent_class)->" + << '\n'; indent_up(); - f_service_ << indent() << "set_property (object, property_id, value, pspec);" << endl; + f_service_ << indent() << "set_property (object, property_id, value, pspec);" << '\n'; indent_down(); } - f_service_ << indent() << "break;" << endl; + f_service_ << indent() << "break;" << '\n'; indent_down(); - f_service_ << indent() << "default:" << endl; + f_service_ << indent() << "default:" << '\n'; indent_up(); f_service_ << indent() << "G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);" - << endl << indent() << "break;" << endl; + << '\n' << indent() << "break;" << '\n'; indent_down(); scope_down(f_service_); scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; // Generate processor's property getter function_name = class_name_lc + "_get_property"; args_indent = string(function_name.length() + 2, ' '); - f_service_ << "static void" << endl << function_name << " (GObject *object," << endl - << args_indent << "guint property_id," << endl << args_indent << "GValue *value," - << endl << args_indent << "GParamSpec *pspec)" << endl; + f_service_ << "static void" << '\n' << function_name << " (GObject *object," << '\n' + << args_indent << "guint property_id," << '\n' << args_indent << "GValue *value," + << '\n' << args_indent << "GParamSpec *pspec)" << '\n'; scope_up(f_service_); - f_service_ << indent() << class_name << " *self = " << class_name_uc << " (object);" << endl - << endl << indent() << "switch (property_id)" << endl; + f_service_ << indent() << class_name << " *self = " << class_name_uc << " (object);" << '\n' + << '\n' << indent() << "switch (property_id)" << '\n'; scope_up(f_service_); - f_service_ << indent() << "case PROP_" << class_name_uc << "_HANDLER:" << endl; + f_service_ << indent() << "case PROP_" << class_name_uc << "_HANDLER:" << '\n'; indent_up(); - f_service_ << indent() << "g_value_set_object (value, self->handler);" << endl << indent() - << "break;" << endl; + f_service_ << indent() << "g_value_set_object (value, self->handler);" << '\n' << indent() + << "break;" << '\n'; indent_down(); - f_service_ << indent() << "default:" << endl; + f_service_ << indent() << "default:" << '\n'; indent_up(); f_service_ << indent() << "G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);" - << endl << indent() << "break;" << endl; + << '\n' << indent() << "break;" << '\n'; indent_down(); scope_down(f_service_); scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; // Generator the processor's dispose function - f_service_ << "static void" << endl << class_name_lc << "_dispose (GObject *gobject)" << endl; + f_service_ << "static void" << '\n' << class_name_lc << "_dispose (GObject *gobject)" << '\n'; scope_up(f_service_); - f_service_ << indent() << class_name << " *self = " << class_name_uc << " (gobject);" << endl - << endl << indent() << "if (self->handler != NULL)" << endl; + f_service_ << indent() << class_name << " *self = " << class_name_uc << " (gobject);" << '\n' + << '\n' << indent() << "if (self->handler != NULL)" << '\n'; scope_up(f_service_); - f_service_ << indent() << "g_object_unref (self->handler);" << endl << indent() - << "self->handler = NULL;" << endl; + f_service_ << indent() << "g_object_unref (self->handler);" << '\n' << indent() + << "self->handler = NULL;" << '\n'; scope_down(f_service_); - f_service_ << endl << indent() << "G_OBJECT_CLASS (" << class_name_lc << "_parent_class)" + f_service_ << '\n' << indent() << "G_OBJECT_CLASS (" << class_name_lc << "_parent_class)" "->dispose (gobject);" - << endl; + << '\n'; scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; // Generate processor finalize function - f_service_ << "static void" << endl << class_name_lc << "_finalize (GObject *gobject)" << endl; + f_service_ << "static void" << '\n' << class_name_lc << "_finalize (GObject *gobject)" << '\n'; scope_up(f_service_); f_service_ << indent() << this->nspace << service_name_ << "Processor *self = " << this->nspace_uc - << service_name_uc << "_PROCESSOR (gobject);" << endl << endl << indent() - << "thrift_safe_hash_table_destroy (self->process_map);" << endl << endl << indent() + << service_name_uc << "_PROCESSOR (gobject);" << '\n' << '\n' << indent() + << "thrift_safe_hash_table_destroy (self->process_map);" << '\n' << '\n' << indent() << "G_OBJECT_CLASS (" << class_name_lc << "_parent_class)" - "->finalize (gobject);" << endl; + "->finalize (gobject);" << '\n'; scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; // Generate processor instance initializer - f_service_ << "static void" << endl << class_name_lc << "_init (" << class_name << " *self)" - << endl; + f_service_ << "static void" << '\n' << class_name_lc << "_init (" << class_name << " *self)" + << '\n'; scope_up(f_service_); if (functions.size() > 0) { - f_service_ << indent() << "guint index;" << endl - << endl; + f_service_ << indent() << "guint index;" << '\n' + << '\n'; } - f_service_ << indent() << "self->handler = NULL;" << endl << indent() + f_service_ << indent() << "self->handler = NULL;" << '\n' << indent() << "self->process_map = " - "g_hash_table_new (g_str_hash, g_str_equal);" << endl; + "g_hash_table_new (g_str_hash, g_str_equal);" << '\n'; if (functions.size() > 0) { args_indent = string(21, ' '); - f_service_ << endl + f_service_ << '\n' << indent() << "for (index = 0; index < " - << functions.size() << "; index += 1)" << endl; + << functions.size() << "; index += 1)" << '\n'; indent_up(); - f_service_ << indent() << "g_hash_table_insert (self->process_map," << endl + f_service_ << indent() << "g_hash_table_insert (self->process_map," << '\n' << indent() << args_indent - << class_name_lc << "_process_function_defs[index].name," << endl + << class_name_lc << "_process_function_defs[index].name," << '\n' << indent() << args_indent << "&" << class_name_lc << "_process_function_defs[index]" << ");" - << endl; + << '\n'; indent_down(); } scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; // Generate processor class initializer - f_service_ << "static void" << endl << class_name_lc << "_class_init (" << class_name - << "Class *cls)" << endl; + f_service_ << "static void" << '\n' << class_name_lc << "_class_init (" << class_name + << "Class *cls)" << '\n'; scope_up(f_service_); - f_service_ << indent() << "GObjectClass *gobject_class = G_OBJECT_CLASS (cls);" << endl - << indent() << "ThriftDispatchProcessorClass *dispatch_processor_class =" << endl; + f_service_ << indent() << "GObjectClass *gobject_class = G_OBJECT_CLASS (cls);" << '\n' + << indent() << "ThriftDispatchProcessorClass *dispatch_processor_class =" << '\n'; indent_up(); - f_service_ << indent() << "THRIFT_DISPATCH_PROCESSOR_CLASS (cls);" << endl; + f_service_ << indent() << "THRIFT_DISPATCH_PROCESSOR_CLASS (cls);" << '\n'; indent_down(); - f_service_ << indent() << "GParamSpec *param_spec;" << endl << endl << indent() - << "gobject_class->dispose = " << class_name_lc << "_dispose;" << endl << indent() - << "gobject_class->finalize = " << class_name_lc << "_finalize;" << endl << indent() - << "gobject_class->set_property = " << class_name_lc << "_set_property;" << endl + f_service_ << indent() << "GParamSpec *param_spec;" << '\n' << '\n' << indent() + << "gobject_class->dispose = " << class_name_lc << "_dispose;" << '\n' << indent() + << "gobject_class->finalize = " << class_name_lc << "_finalize;" << '\n' << indent() + << "gobject_class->set_property = " << class_name_lc << "_set_property;" << '\n' << indent() << "gobject_class->get_property = " << class_name_lc << "_get_property;" - << endl << endl << indent() + << '\n' << '\n' << indent() << "dispatch_processor_class->dispatch_call = " << class_name_lc << "_dispatch_call;" - << endl << indent() << "cls->dispatch_call = " << class_name_lc << "_dispatch_call;" - << endl << endl << indent() << "param_spec = g_param_spec_object (\"handler\"," - << endl; + << '\n' << indent() << "cls->dispatch_call = " << class_name_lc << "_dispatch_call;" + << '\n' << '\n' << indent() << "param_spec = g_param_spec_object (\"handler\"," + << '\n'; args_indent = indent() + string(34, ' '); - f_service_ << args_indent << "\"Service handler implementation\"," << endl << args_indent - << "\"The service handler implementation \"" << endl << args_indent - << "\"to which method calls are dispatched.\"," << endl << args_indent - << this->nspace_uc + "TYPE_" + service_name_uc + "_HANDLER," << endl << args_indent - << "G_PARAM_READWRITE);" << endl; - f_service_ << indent() << "g_object_class_install_property (gobject_class," << endl; + f_service_ << args_indent << "\"Service handler implementation\"," << '\n' << args_indent + << "\"The service handler implementation \"" << '\n' << args_indent + << "\"to which method calls are dispatched.\"," << '\n' << args_indent + << this->nspace_uc + "TYPE_" + service_name_uc + "_HANDLER," << '\n' << args_indent + << "G_PARAM_READWRITE);" << '\n'; + f_service_ << indent() << "g_object_class_install_property (gobject_class," << '\n'; args_indent = indent() + string(33, ' '); - f_service_ << args_indent << "PROP_" << class_name_uc << "_HANDLER," << endl << args_indent - << "param_spec);" << endl; + f_service_ << args_indent << "PROP_" << class_name_uc << "_HANDLER," << '\n' << args_indent + << "param_spec);" << '\n'; scope_down(f_service_); } @@ -2807,60 +2805,60 @@ void t_c_glib_generator::generate_object(t_struct* tstruct) { string args_indent; // write the instance definition - f_types_ << "struct _" << this->nspace << name << endl << "{ " << endl - << " ThriftStruct parent; " << endl << endl << " /* public */" << endl; + f_types_ << "struct _" << this->nspace << name << '\n' << "{ " << '\n' + << " ThriftStruct parent; " << '\n' << '\n' << " /* public */" << '\n'; // for each field, add a member variable vector::const_iterator m_iter; const vector& members = tstruct->get_members(); for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { t_type* t = get_true_type((*m_iter)->get_type()); - f_types_ << " " << type_name(t) << " " << (*m_iter)->get_name() << ";" << endl; + f_types_ << " " << type_name(t) << " " << (*m_iter)->get_name() << ";" << '\n'; if ((*m_iter)->get_req() != t_field::T_REQUIRED) { - f_types_ << " gboolean __isset_" << (*m_iter)->get_name() << ";" << endl; + f_types_ << " gboolean __isset_" << (*m_iter)->get_name() << ";" << '\n'; } } // close the structure definition and create a typedef - f_types_ << "};" << endl << "typedef struct _" << this->nspace << name << " " << this->nspace - << name << ";" << endl << endl; + f_types_ << "};" << '\n' << "typedef struct _" << this->nspace << name << " " << this->nspace + << name << ";" << '\n' << '\n'; // write the class definition - f_types_ << "struct _" << this->nspace << name << "Class" << endl << "{" << endl - << " ThriftStructClass parent;" << endl << "};" << endl << "typedef struct _" - << this->nspace << name << "Class " << this->nspace << name << "Class;" << endl << endl; + f_types_ << "struct _" << this->nspace << name << "Class" << '\n' << "{" << '\n' + << " ThriftStructClass parent;" << '\n' << "};" << '\n' << "typedef struct _" + << this->nspace << name << "Class " << this->nspace << name << "Class;" << '\n' << '\n'; // write the standard GObject boilerplate - f_types_ << "GType " << this->nspace_lc << name_u << "_get_type (void);" << endl << "#define " + f_types_ << "GType " << this->nspace_lc << name_u << "_get_type (void);" << '\n' << "#define " << this->nspace_uc << "TYPE_" << name_uc << " (" << this->nspace_lc << name_u - << "_get_type())" << endl << "#define " << this->nspace_uc << name_uc + << "_get_type())" << '\n' << "#define " << this->nspace_uc << name_uc << "(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), " << this->nspace_uc << "TYPE_" << name_uc - << ", " << this->nspace << name << "))" << endl << "#define " << this->nspace_uc + << ", " << this->nspace << name << "))" << '\n' << "#define " << this->nspace_uc << name_uc << "_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), " << this->nspace_uc << "_TYPE_" - << name_uc << ", " << this->nspace << name << "Class))" << endl << "#define " + << name_uc << ", " << this->nspace << name << "Class))" << '\n' << "#define " << this->nspace_uc << "IS_" << name_uc << "(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), " - << this->nspace_uc << "TYPE_" << name_uc << "))" << endl << "#define " << this->nspace_uc + << this->nspace_uc << "TYPE_" << name_uc << "))" << '\n' << "#define " << this->nspace_uc << "IS_" << name_uc << "_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), " << this->nspace_uc - << "TYPE_" << name_uc << "))" << endl << "#define " << this->nspace_uc << name_uc + << "TYPE_" << name_uc << "))" << '\n' << "#define " << this->nspace_uc << name_uc << "_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), " << this->nspace_uc << "TYPE_" - << name_uc << ", " << this->nspace << name << "Class))" << endl << endl; + << name_uc << ", " << this->nspace << name << "Class))" << '\n' << '\n'; // start writing the object implementation .c file // generate properties enum if (members.size() > 0) { - f_types_impl_ << "enum _" << class_name << "Properties" << endl << "{" << endl; + f_types_impl_ << "enum _" << class_name << "Properties" << '\n' << "{" << '\n'; indent_up(); f_types_impl_ << indent() << "PROP_" << class_name_uc << "_0"; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { string member_name_uc = to_upper_case(to_lower_case(initial_caps_to_underscores((*m_iter)->get_name()))); - f_types_impl_ << "," << endl << indent() << "PROP_" << class_name_uc << "_" << member_name_uc; + f_types_impl_ << "," << '\n' << indent() << "PROP_" << class_name_uc << "_" << member_name_uc; } - f_types_impl_ << endl; + f_types_impl_ << '\n'; indent_down(); - f_types_impl_ << "};" << endl << endl; + f_types_impl_ << "};" << '\n' << '\n'; } // generate struct I/O methods @@ -2874,12 +2872,12 @@ void t_c_glib_generator::generate_object(t_struct* tstruct) { // generate property setter function_name = class_name_lc + "_set_property"; args_indent = string(function_name.length() + 2, ' '); - f_types_impl_ << "static void" << endl << function_name << " (GObject *object," << endl - << args_indent << "guint property_id," << endl << args_indent - << "const GValue *value," << endl << args_indent << "GParamSpec *pspec)" << endl; + f_types_impl_ << "static void" << '\n' << function_name << " (GObject *object," << '\n' + << args_indent << "guint property_id," << '\n' << args_indent + << "const GValue *value," << '\n' << args_indent << "GParamSpec *pspec)" << '\n'; scope_up(f_types_impl_); - f_types_impl_ << indent() << class_name << " *self = " << class_name_uc << " (object);" << endl - << endl << indent() << "switch (property_id)" << endl; + f_types_impl_ << indent() << class_name << " *self = " << class_name_uc << " (object);" << '\n' + << '\n' << indent() << "switch (property_id)" << '\n'; scope_up(f_types_impl_); for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { t_field* member = (*m_iter); @@ -2890,7 +2888,7 @@ void t_c_glib_generator::generate_object(t_struct* tstruct) { string property_identifier = "PROP_" + class_name_uc + "_" + member_name_uc; - f_types_impl_ << indent() << "case " << property_identifier + ":" << endl; + f_types_impl_ << indent() << "case " << property_identifier + ":" << '\n'; indent_up(); if (member_type->is_base_type()) { @@ -2900,7 +2898,7 @@ void t_c_glib_generator::generate_object(t_struct* tstruct) { if (base_type->get_base() == t_base_type::TYPE_STRING) { string release_function_name; - f_types_impl_ << indent() << "if (self->" << member_name << " != NULL)" << endl; + f_types_impl_ << indent() << "if (self->" << member_name << " != NULL)" << '\n'; indent_up(); if (base_type->is_binary()) { @@ -2912,7 +2910,7 @@ void t_c_glib_generator::generate_object(t_struct* tstruct) { } f_types_impl_ << indent() << release_function_name << " (self->" << member_name << ");" - << endl; + << '\n'; indent_down(); } else { switch (base_type->get_base()) { @@ -2944,10 +2942,10 @@ void t_c_glib_generator::generate_object(t_struct* tstruct) { } f_types_impl_ << indent() << "self->" << member_name << " = " << assign_function_name - << " (value);" << endl; + << " (value);" << '\n'; } else if (member_type->is_enum()) { f_types_impl_ << indent() << "self->" << member_name << " = g_value_get_int (value);" - << endl; + << '\n'; } else if (member_type->is_container()) { string release_function_name; string assign_function_name; @@ -2969,47 +2967,47 @@ void t_c_glib_generator::generate_object(t_struct* tstruct) { assign_function_name = "g_value_dup_boxed"; } - f_types_impl_ << indent() << "if (self->" << member_name << " != NULL)" << endl; + f_types_impl_ << indent() << "if (self->" << member_name << " != NULL)" << '\n'; indent_up(); f_types_impl_ << indent() << release_function_name << " (self->" << member_name << ");" - << endl; + << '\n'; indent_down(); f_types_impl_ << indent() << "self->" << member_name << " = " << assign_function_name - << " (value);" << endl; + << " (value);" << '\n'; } else if (member_type->is_struct() || member_type->is_xception()) { - f_types_impl_ << indent() << "if (self->" << member_name << " != NULL)" << endl; + f_types_impl_ << indent() << "if (self->" << member_name << " != NULL)" << '\n'; indent_up(); - f_types_impl_ << indent() << "g_object_unref (self->" << member_name << ");" << endl; + f_types_impl_ << indent() << "g_object_unref (self->" << member_name << ");" << '\n'; indent_down(); f_types_impl_ << indent() << "self->" << member_name << " = g_value_dup_object (value);" - << endl; + << '\n'; } if (member->get_req() != t_field::T_REQUIRED) { - f_types_impl_ << indent() << "self->__isset_" << member_name << " = TRUE;" << endl; + f_types_impl_ << indent() << "self->__isset_" << member_name << " = TRUE;" << '\n'; } - f_types_impl_ << indent() << "break;" << endl << endl; + f_types_impl_ << indent() << "break;" << '\n' << '\n'; indent_down(); } - f_types_impl_ << indent() << "default:" << endl; + f_types_impl_ << indent() << "default:" << '\n'; indent_up(); f_types_impl_ << indent() << "G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);" - << endl << indent() << "break;" << endl; + << '\n' << indent() << "break;" << '\n'; indent_down(); scope_down(f_types_impl_); scope_down(f_types_impl_); - f_types_impl_ << endl; + f_types_impl_ << '\n'; // generate property getter function_name = class_name_lc + "_get_property"; args_indent = string(function_name.length() + 2, ' '); - f_types_impl_ << "static void" << endl << function_name << " (GObject *object," << endl - << args_indent << "guint property_id," << endl << args_indent << "GValue *value," - << endl << args_indent << "GParamSpec *pspec)" << endl; + f_types_impl_ << "static void" << '\n' << function_name << " (GObject *object," << '\n' + << args_indent << "guint property_id," << '\n' << args_indent << "GValue *value," + << '\n' << args_indent << "GParamSpec *pspec)" << '\n'; scope_up(f_types_impl_); - f_types_impl_ << indent() << class_name << " *self = " << class_name_uc << " (object);" << endl - << endl << indent() << "switch (property_id)" << endl; + f_types_impl_ << indent() << class_name << " *self = " << class_name_uc << " (object);" << '\n' + << '\n' << indent() << "switch (property_id)" << '\n'; scope_up(f_types_impl_); for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { t_field* member = (*m_iter); @@ -3070,26 +3068,26 @@ void t_c_glib_generator::generate_object(t_struct* tstruct) { "unrecognized type for struct member \"" + member_name + "\""; } - f_types_impl_ << indent() << "case " << property_identifier + ":" << endl; + f_types_impl_ << indent() << "case " << property_identifier + ":" << '\n'; indent_up(); f_types_impl_ << indent() << setter_function_name << " (value, self->" << member_name << ");" - << endl << indent() << "break;" << endl << endl; + << '\n' << indent() << "break;" << '\n' << '\n'; indent_down(); } - f_types_impl_ << indent() << "default:" << endl; + f_types_impl_ << indent() << "default:" << '\n'; indent_up(); f_types_impl_ << indent() << "G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);" - << endl << indent() << "break;" << endl; + << '\n' << indent() << "break;" << '\n'; indent_down(); scope_down(f_types_impl_); scope_down(f_types_impl_); - f_types_impl_ << endl; + f_types_impl_ << '\n'; } // generate the instance init function - f_types_impl_ << "static void " << endl << this->nspace_lc << name_u << "_instance_init (" - << this->nspace << name << " * object)" << endl << "{" << endl; + f_types_impl_ << "static void " << '\n' << this->nspace_lc << name_u << "_instance_init (" + << this->nspace << name << " * object)" << '\n' << "{" << '\n'; indent_up(); // generate default-value structures for container-type members @@ -3109,9 +3107,9 @@ void t_c_glib_generator::generate_object(t_struct* tstruct) { // Generate an array with the list literal indent(f_types_impl_) << "static " << type_name(elem_type, false, true) << " __default_" - << member_name << "[" << list.size() << "] = " << endl; + << member_name << "[" << list.size() << "] = " << '\n'; indent_up(); - f_types_impl_ << indent() << constant_literal(member_type, member_value) << ";" << endl; + f_types_impl_ << indent() << constant_literal(member_type, member_value) << ";" << '\n'; indent_down(); constant_declaration_output = true; @@ -3129,15 +3127,15 @@ void t_c_glib_generator::generate_object(t_struct* tstruct) { } if (constant_declaration_output) { if (string_list_constant_output) { - indent(f_types_impl_) << "unsigned int list_index;" << endl; + indent(f_types_impl_) << "unsigned int list_index;" << '\n'; } - f_types_impl_ << endl; + f_types_impl_ << '\n'; } // satisfy compilers with -Wall turned on - indent(f_types_impl_) << "/* satisfy -Wall */" << endl << indent() - << "THRIFT_UNUSED_VAR (object);" << endl; + indent(f_types_impl_) << "/* satisfy -Wall */" << '\n' << indent() + << "THRIFT_UNUSED_VAR (object);" << '\n'; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { t_type* member_type = (*m_iter)->get_type(); @@ -3153,7 +3151,7 @@ void t_c_glib_generator::generate_object(t_struct* tstruct) { } else { dval += t->is_string() ? "NULL" : "0"; } - indent(f_types_impl_) << "object->" << (*m_iter)->get_name() << dval << ";" << endl; + indent(f_types_impl_) << "object->" << (*m_iter)->get_name() << dval << ";" << '\n'; } else if (t->is_struct()) { string name = (*m_iter)->get_name(); t_program* type_program = member_type->get_program(); @@ -3163,10 +3161,10 @@ void t_c_glib_generator::generate_object(t_struct* tstruct) { string type_name_uc = to_upper_case(initial_caps_to_underscores(member_type->get_name())); indent(f_types_impl_) << "object->" << name << " = g_object_new (" << to_upper_case(type_nspace_prefix) << "TYPE_" << type_name_uc - << ", NULL);" << endl; + << ", NULL);" << '\n'; } else if (t->is_xception()) { string name = (*m_iter)->get_name(); - indent(f_types_impl_) << "object->" << name << " = NULL;" << endl; + indent(f_types_impl_) << "object->" << name << " = NULL;" << '\n'; } else if (t->is_container()) { string name = (*m_iter)->get_name(); string init_function; @@ -3184,7 +3182,7 @@ void t_c_glib_generator::generate_object(t_struct* tstruct) { init_function = generate_new_array_from_type(etype); } - indent(f_types_impl_) << "object->" << name << " = " << init_function << endl; + indent(f_types_impl_) << "object->" << name << " = " << init_function << '\n'; // Pre-populate the container with the specified default values, if any if ((*m_iter)->get_value()) { @@ -3196,17 +3194,17 @@ void t_c_glib_generator::generate_object(t_struct* tstruct) { if (is_numeric(etype)) { indent(f_types_impl_) << "g_array_append_vals (object->" << name << ", &__default_" << - name << ", " << list.size() << ");" << endl; + name << ", " << list.size() << ");" << '\n'; } else { indent(f_types_impl_) << "for (list_index = 0; list_index < " << list.size() << "; " << - "list_index += 1)" << endl; + "list_index += 1)" << '\n'; indent_up(); indent(f_types_impl_) << - "g_ptr_array_add (object->" << name << "," << endl << + "g_ptr_array_add (object->" << name << "," << '\n' << indent() << string(17, ' ') << "g_strdup (__default_" << - name << "[list_index]));" << endl; + name << "[list_index]));" << '\n'; indent_down(); } } @@ -3217,36 +3215,36 @@ void t_c_glib_generator::generate_object(t_struct* tstruct) { /* if not required, initialize the __isset variable */ if ((*m_iter)->get_req() != t_field::T_REQUIRED) { - indent(f_types_impl_) << "object->__isset_" << (*m_iter)->get_name() << " = FALSE;" << endl; + indent(f_types_impl_) << "object->__isset_" << (*m_iter)->get_name() << " = FALSE;" << '\n'; } } indent_down(); - f_types_impl_ << "}" << endl << endl; + f_types_impl_ << "}" << '\n' << '\n'; /* create the destructor */ - f_types_impl_ << "static void " << endl << this->nspace_lc << name_u - << "_finalize (GObject *object)" << endl << "{" << endl; + f_types_impl_ << "static void " << '\n' << this->nspace_lc << name_u + << "_finalize (GObject *object)" << '\n' << "{" << '\n'; indent_up(); f_types_impl_ << indent() << this->nspace << name << " *tobject = " << this->nspace_uc << name_uc - << " (object);" << endl << endl; + << " (object);" << '\n' << '\n'; - f_types_impl_ << indent() << "/* satisfy -Wall in case we don't use tobject */" << endl - << indent() << "THRIFT_UNUSED_VAR (tobject);" << endl; + f_types_impl_ << indent() << "/* satisfy -Wall in case we don't use tobject */" << '\n' + << indent() << "THRIFT_UNUSED_VAR (tobject);" << '\n'; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { t_type* t = get_true_type((*m_iter)->get_type()); if (t->is_container()) { string name = (*m_iter)->get_name(); if (t->is_map() || t->is_set()) { - f_types_impl_ << indent() << "if (tobject->" << name << " != NULL)" << endl; - f_types_impl_ << indent() << "{" << endl; + f_types_impl_ << indent() << "if (tobject->" << name << " != NULL)" << '\n'; + f_types_impl_ << indent() << "{" << '\n'; indent_up(); - f_types_impl_ << indent() << "g_hash_table_destroy (tobject->" << name << ");" << endl; - f_types_impl_ << indent() << "tobject->" << name << " = NULL;" << endl; + f_types_impl_ << indent() << "g_hash_table_destroy (tobject->" << name << ");" << '\n'; + f_types_impl_ << indent() << "tobject->" << name << " = NULL;" << '\n'; indent_down(); - f_types_impl_ << indent() << "}" << endl; + f_types_impl_ << indent() << "}" << '\n'; } else if (t->is_list()) { t_type* etype = ((t_list*)t)->get_elem_type(); string destructor_function = "g_ptr_array_unref"; @@ -3273,59 +3271,59 @@ void t_c_glib_generator::generate_object(t_struct* tstruct) { destructor_function = "g_array_unref"; } - f_types_impl_ << indent() << "if (tobject->" << name << " != NULL)" << endl; - f_types_impl_ << indent() << "{" << endl; + f_types_impl_ << indent() << "if (tobject->" << name << " != NULL)" << '\n'; + f_types_impl_ << indent() << "{" << '\n'; indent_up(); - f_types_impl_ << indent() << destructor_function << " (tobject->" << name << ");" << endl; - f_types_impl_ << indent() << "tobject->" << name << " = NULL;" << endl; + f_types_impl_ << indent() << destructor_function << " (tobject->" << name << ");" << '\n'; + f_types_impl_ << indent() << "tobject->" << name << " = NULL;" << '\n'; indent_down(); - f_types_impl_ << indent() << "}" << endl; + f_types_impl_ << indent() << "}" << '\n'; } } else if (t->is_struct() || t->is_xception()) { string name = (*m_iter)->get_name(); // TODO: g_clear_object needs glib >= 2.28 - // f_types_impl_ << indent() << "g_clear_object (&(tobject->" << name << "));" << endl; + // f_types_impl_ << indent() << "g_clear_object (&(tobject->" << name << "));" << '\n'; // does g_object_unref the trick? - f_types_impl_ << indent() << "if (tobject->" << name << " != NULL)" << endl; - f_types_impl_ << indent() << "{" << endl; + f_types_impl_ << indent() << "if (tobject->" << name << " != NULL)" << '\n'; + f_types_impl_ << indent() << "{" << '\n'; indent_up(); - f_types_impl_ << indent() << "g_object_unref(tobject->" << name << ");" << endl; - f_types_impl_ << indent() << "tobject->" << name << " = NULL;" << endl; + f_types_impl_ << indent() << "g_object_unref(tobject->" << name << ");" << '\n'; + f_types_impl_ << indent() << "tobject->" << name << " = NULL;" << '\n'; indent_down(); - f_types_impl_ << indent() << "}" << endl; + f_types_impl_ << indent() << "}" << '\n'; } else if (t->is_string()) { string name = (*m_iter)->get_name(); - f_types_impl_ << indent() << "if (tobject->" << name << " != NULL)" << endl; - f_types_impl_ << indent() << "{" << endl; + f_types_impl_ << indent() << "if (tobject->" << name << " != NULL)" << '\n'; + f_types_impl_ << indent() << "{" << '\n'; indent_up(); f_types_impl_ << indent() << generate_free_func_from_type(t) << "(tobject->" << name << ");" - << endl; - f_types_impl_ << indent() << "tobject->" << name << " = NULL;" << endl; + << '\n'; + f_types_impl_ << indent() << "tobject->" << name << " = NULL;" << '\n'; indent_down(); - f_types_impl_ << indent() << "}" << endl; + f_types_impl_ << indent() << "}" << '\n'; } } indent_down(); - f_types_impl_ << "}" << endl << endl; + f_types_impl_ << "}" << '\n' << '\n'; // generate the class init function - f_types_impl_ << "static void" << endl << class_name_lc << "_class_init (" << class_name - << "Class * cls)" << endl; + f_types_impl_ << "static void" << '\n' << class_name_lc << "_class_init (" << class_name + << "Class * cls)" << '\n'; scope_up(f_types_impl_); - f_types_impl_ << indent() << "GObjectClass *gobject_class = G_OBJECT_CLASS (cls);" << endl + f_types_impl_ << indent() << "GObjectClass *gobject_class = G_OBJECT_CLASS (cls);" << '\n' << indent() << "ThriftStructClass *struct_class = " - << "THRIFT_STRUCT_CLASS (cls);" << endl << endl << indent() - << "struct_class->read = " << class_name_lc << "_read;" << endl << indent() - << "struct_class->write = " << class_name_lc << "_write;" << endl << endl + << "THRIFT_STRUCT_CLASS (cls);" << '\n' << '\n' << indent() + << "struct_class->read = " << class_name_lc << "_read;" << '\n' << indent() + << "struct_class->write = " << class_name_lc << "_write;" << '\n' << '\n' << indent() << "gobject_class->finalize = " << class_name_lc << "_finalize;" - << endl; + << '\n'; if (members.size() > 0) { f_types_impl_ << indent() << "gobject_class->get_property = " << class_name_lc - << "_get_property;" << endl << indent() - << "gobject_class->set_property = " << class_name_lc << "_set_property;" << endl; + << "_get_property;" << '\n' << indent() + << "gobject_class->set_property = " << class_name_lc << "_set_property;" << '\n'; // install a property for each member for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { @@ -3338,11 +3336,11 @@ void t_c_glib_generator::generate_object(t_struct* tstruct) { string property_identifier = "PROP_" + class_name_uc + "_" + member_name_uc; - f_types_impl_ << endl << indent() << "g_object_class_install_property" << endl; + f_types_impl_ << '\n' << indent() << "g_object_class_install_property" << '\n'; indent_up(); args_indent = indent() + ' '; - f_types_impl_ << indent() << "(gobject_class," << endl << args_indent << property_identifier - << "," << endl << args_indent; + f_types_impl_ << indent() << "(gobject_class," << '\n' << args_indent << property_identifier + << "," << '\n' << args_indent; if (member_type->is_base_type()) { t_base_type::t_base base_type = ((t_base_type*)member_type)->get_base(); @@ -3350,27 +3348,27 @@ void t_c_glib_generator::generate_object(t_struct* tstruct) { if (base_type == t_base_type::TYPE_STRING) { if (((t_base_type*)member_type)->is_binary()) { args_indent += string(20, ' '); - f_types_impl_ << "g_param_spec_boxed (\"" << member_name << "\"," << endl << args_indent - << "NULL," << endl << args_indent << "NULL," << endl << args_indent - << "G_TYPE_BYTE_ARRAY," << endl << args_indent << "G_PARAM_READWRITE));" - << endl; + f_types_impl_ << "g_param_spec_boxed (\"" << member_name << "\"," << '\n' << args_indent + << "NULL," << '\n' << args_indent << "NULL," << '\n' << args_indent + << "G_TYPE_BYTE_ARRAY," << '\n' << args_indent << "G_PARAM_READWRITE));" + << '\n'; } else { args_indent += string(21, ' '); - f_types_impl_ << "g_param_spec_string (\"" << member_name << "\"," << endl - << args_indent << "NULL," << endl << args_indent << "NULL," << endl + f_types_impl_ << "g_param_spec_string (\"" << member_name << "\"," << '\n' + << args_indent << "NULL," << '\n' << args_indent << "NULL," << '\n' << args_indent << ((member_value != NULL) ? "\"" + member_value->get_string() + "\"" - : "NULL") << "," << endl << args_indent - << "G_PARAM_READWRITE));" << endl; + : "NULL") << "," << '\n' << args_indent + << "G_PARAM_READWRITE));" << '\n'; } } else if (base_type == t_base_type::TYPE_BOOL) { args_indent += string(22, ' '); - f_types_impl_ << "g_param_spec_boolean (\"" << member_name << "\"," << endl << args_indent - << "NULL," << endl << args_indent << "NULL," << endl << args_indent + f_types_impl_ << "g_param_spec_boolean (\"" << member_name << "\"," << '\n' << args_indent + << "NULL," << '\n' << args_indent << "NULL," << '\n' << args_indent << (((member_value != NULL) && (member_value->get_integer() != 0)) ? "TRUE" - : "FALSE") << "," << endl << args_indent << "G_PARAM_READWRITE));" - << endl; + : "FALSE") << "," << '\n' << args_indent << "G_PARAM_READWRITE));" + << '\n'; } else if ((base_type == t_base_type::TYPE_I8) || (base_type == t_base_type::TYPE_I16) || (base_type == t_base_type::TYPE_I32) || (base_type == t_base_type::TYPE_I64) || (base_type == t_base_type::TYPE_DOUBLE)) { @@ -3423,11 +3421,11 @@ void t_c_glib_generator::generate_object(t_struct* tstruct) { } args_indent += string(param_spec_function_name.length() + 2, ' '); - f_types_impl_ << param_spec_function_name << " (\"" << member_name << "\"," << endl - << args_indent << "NULL," << endl << args_indent << "NULL," << endl - << args_indent << min_value << "," << endl << args_indent << max_value - << "," << endl << args_indent << default_value.str() << "," << endl - << args_indent << "G_PARAM_READWRITE));" << endl; + f_types_impl_ << param_spec_function_name << " (\"" << member_name << "\"," << '\n' + << args_indent << "NULL," << '\n' << args_indent << "NULL," << '\n' + << args_indent << min_value << "," << '\n' << args_indent << max_value + << "," << '\n' << args_indent << default_value.str() << "," << '\n' + << args_indent << "G_PARAM_READWRITE));" << '\n'; } indent_down(); @@ -3438,11 +3436,11 @@ void t_c_glib_generator::generate_object(t_struct* tstruct) { int max_value = (enum_max_value != nullptr) ? enum_max_value->get_value() : 0; args_indent += string(18, ' '); - f_types_impl_ << "g_param_spec_int (\"" << member_name << "\"," << endl << args_indent - << "NULL," << endl << args_indent << "NULL," << endl << args_indent - << min_value << "," << endl << args_indent << max_value << "," << endl - << args_indent << min_value << "," << endl << args_indent - << "G_PARAM_READWRITE));" << endl; + f_types_impl_ << "g_param_spec_int (\"" << member_name << "\"," << '\n' << args_indent + << "NULL," << '\n' << args_indent << "NULL," << '\n' << args_indent + << min_value << "," << '\n' << args_indent << max_value << "," << '\n' + << args_indent << min_value << "," << '\n' << args_indent + << "G_PARAM_READWRITE));" << '\n'; indent_down(); } else if (member_type->is_struct() || member_type->is_xception()) { t_program* type_program = member_type->get_program(); @@ -3454,9 +3452,9 @@ void t_c_glib_generator::generate_object(t_struct* tstruct) { + to_upper_case(initial_caps_to_underscores(member_type->get_name())); args_indent += string(20, ' '); - f_types_impl_ << "g_param_spec_object (\"" << member_name << "\"," << endl << args_indent - << "NULL," << endl << args_indent << "NULL," << endl << args_indent - << param_type << "," << endl << args_indent << "G_PARAM_READWRITE));" << endl; + f_types_impl_ << "g_param_spec_object (\"" << member_name << "\"," << '\n' << args_indent + << "NULL," << '\n' << args_indent << "NULL," << '\n' << args_indent + << param_type << "," << '\n' << args_indent << "G_PARAM_READWRITE));" << '\n'; indent_down(); } else if (member_type->is_list()) { t_type* elem_type = ((t_list*)member_type)->get_elem_type(); @@ -3469,38 +3467,38 @@ void t_c_glib_generator::generate_object(t_struct* tstruct) { } args_indent += string(20, ' '); - f_types_impl_ << "g_param_spec_boxed (\"" << member_name << "\"," << endl << args_indent - << "NULL," << endl << args_indent << "NULL," << endl << args_indent - << param_type << "," << endl << args_indent << "G_PARAM_READWRITE));" << endl; + f_types_impl_ << "g_param_spec_boxed (\"" << member_name << "\"," << '\n' << args_indent + << "NULL," << '\n' << args_indent << "NULL," << '\n' << args_indent + << param_type << "," << '\n' << args_indent << "G_PARAM_READWRITE));" << '\n'; indent_down(); } else if (member_type->is_set() || member_type->is_map()) { args_indent += string(20, ' '); - f_types_impl_ << "g_param_spec_boxed (\"" << member_name << "\"," << endl << args_indent - << "NULL," << endl << args_indent << "NULL," << endl << args_indent - << "G_TYPE_HASH_TABLE," << endl << args_indent << "G_PARAM_READWRITE));" - << endl; + f_types_impl_ << "g_param_spec_boxed (\"" << member_name << "\"," << '\n' << args_indent + << "NULL," << '\n' << args_indent << "NULL," << '\n' << args_indent + << "G_TYPE_HASH_TABLE," << '\n' << args_indent << "G_PARAM_READWRITE));" + << '\n'; indent_down(); } } } scope_down(f_types_impl_); - f_types_impl_ << endl; - - f_types_impl_ << "GType" << endl << this->nspace_lc << name_u << "_get_type (void)" << endl << "{" - << endl << " static GType type = 0;" << endl << endl << " if (type == 0) " << endl - << " {" << endl << " static const GTypeInfo type_info = " << endl << " {" - << endl << " sizeof (" << this->nspace << name << "Class)," << endl - << " NULL, /* base_init */" << endl << " NULL, /* base_finalize */" - << endl << " (GClassInitFunc) " << this->nspace_lc << name_u << "_class_init," - << endl << " NULL, /* class_finalize */" << endl - << " NULL, /* class_data */" << endl << " sizeof (" << this->nspace - << name << ")," << endl << " 0, /* n_preallocs */" << endl + f_types_impl_ << '\n'; + + f_types_impl_ << "GType" << '\n' << this->nspace_lc << name_u << "_get_type (void)" << '\n' << "{" + << '\n' << " static GType type = 0;" << '\n' << '\n' << " if (type == 0) " << '\n' + << " {" << '\n' << " static const GTypeInfo type_info = " << '\n' << " {" + << '\n' << " sizeof (" << this->nspace << name << "Class)," << '\n' + << " NULL, /* base_init */" << '\n' << " NULL, /* base_finalize */" + << '\n' << " (GClassInitFunc) " << this->nspace_lc << name_u << "_class_init," + << '\n' << " NULL, /* class_finalize */" << '\n' + << " NULL, /* class_data */" << '\n' << " sizeof (" << this->nspace + << name << ")," << '\n' << " 0, /* n_preallocs */" << '\n' << " (GInstanceInitFunc) " << this->nspace_lc << name_u << "_instance_init," - << endl << " NULL, /* value_table */" << endl << " };" << endl << endl - << " type = g_type_register_static (THRIFT_TYPE_STRUCT, " << endl + << '\n' << " NULL, /* value_table */" << '\n' << " };" << '\n' << '\n' + << " type = g_type_register_static (THRIFT_TYPE_STRUCT, " << '\n' << " \"" << this->nspace << name << "Type\"," - << endl << " &type_info, 0);" << endl << " }" - << endl << endl << " return type;" << endl << "}" << endl << endl; + << '\n' << " &type_info, 0);" << '\n' << " }" + << '\n' << '\n' << " return type;" << '\n' << "}" << '\n' << '\n'; } /** @@ -3521,59 +3519,59 @@ void t_c_glib_generator::generate_struct_writer(ostream& out, if (is_function) { error_ret = -1; - indent(out) << "static gint32" << endl << this->nspace_lc << name_u + indent(out) << "static gint32" << '\n' << this->nspace_lc << name_u << "_write (ThriftStruct *object, ThriftProtocol *protocol, GError **error)" - << endl; + << '\n'; } - indent(out) << "{" << endl; + indent(out) << "{" << '\n'; indent_up(); - out << indent() << "gint32 ret;" << endl << indent() << "gint32 xfer = 0;" << endl << endl; + out << indent() << "gint32 ret;" << '\n' << indent() << "gint32 xfer = 0;" << '\n' << '\n'; - indent(out) << this_get << endl; + indent(out) << this_get << '\n'; // satisfy -Wall in the case of an empty struct if (!this_get.empty()) { - indent(out) << "THRIFT_UNUSED_VAR (this_object);" << endl; + indent(out) << "THRIFT_UNUSED_VAR (this_object);" << '\n'; } out << indent() << "if ((ret = thrift_protocol_write_struct_begin (protocol, \"" << name - << "\", error)) < 0)" << endl << indent() << " return " << error_ret << ";" << endl - << indent() << "xfer += ret;" << endl; + << "\", error)) < 0)" << '\n' << indent() << " return " << error_ret << ";" << '\n' + << indent() << "xfer += ret;" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if ((*f_iter)->get_req() == t_field::T_OPTIONAL) { - indent(out) << "if (this_object->__isset_" << (*f_iter)->get_name() << " == TRUE) {" << endl; + indent(out) << "if (this_object->__isset_" << (*f_iter)->get_name() << " == TRUE) {" << '\n'; indent_up(); } out << indent() << "if ((ret = thrift_protocol_write_field_begin (protocol, " << "\"" << (*f_iter)->get_name() << "\", " << type_to_enum((*f_iter)->get_type()) << ", " - << (*f_iter)->get_key() << ", error)) < 0)" << endl << indent() << " return " << error_ret - << ";" << endl << indent() << "xfer += ret;" << endl; + << (*f_iter)->get_key() << ", error)) < 0)" << '\n' << indent() << " return " << error_ret + << ";" << '\n' << indent() << "xfer += ret;" << '\n'; generate_serialize_field(out, *f_iter, this_name, "", error_ret); - out << indent() << "if ((ret = thrift_protocol_write_field_end (protocol, error)) < 0)" << endl - << indent() << " return " << error_ret << ";" << endl << indent() << "xfer += ret;" - << endl; + out << indent() << "if ((ret = thrift_protocol_write_field_end (protocol, error)) < 0)" << '\n' + << indent() << " return " << error_ret << ";" << '\n' << indent() << "xfer += ret;" + << '\n'; if ((*f_iter)->get_req() == t_field::T_OPTIONAL) { indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } } // write the struct map - out << indent() << "if ((ret = thrift_protocol_write_field_stop (protocol, error)) < 0)" << endl - << indent() << " return " << error_ret << ";" << endl << indent() << "xfer += ret;" << endl - << indent() << "if ((ret = thrift_protocol_write_struct_end (protocol, error)) < 0)" << endl - << indent() << " return " << error_ret << ";" << endl << indent() << "xfer += ret;" << endl - << endl; + out << indent() << "if ((ret = thrift_protocol_write_field_stop (protocol, error)) < 0)" << '\n' + << indent() << " return " << error_ret << ";" << '\n' << indent() << "xfer += ret;" << '\n' + << indent() << "if ((ret = thrift_protocol_write_struct_end (protocol, error)) < 0)" << '\n' + << indent() << " return " << error_ret << ";" << '\n' << indent() << "xfer += ret;" << '\n' + << '\n'; if (is_function) { - indent(out) << "return xfer;" << endl; + indent(out) << "return xfer;" << '\n'; } indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } /** @@ -3593,127 +3591,127 @@ void t_c_glib_generator::generate_struct_reader(ostream& out, if (is_function) { error_ret = -1; - indent(out) << "/* reads a " << name_u << " object */" << endl << "static gint32" << endl + indent(out) << "/* reads a " << name_u << " object */" << '\n' << "static gint32" << '\n' << this->nspace_lc << name_u - << "_read (ThriftStruct *object, ThriftProtocol *protocol, GError **error)" << endl; + << "_read (ThriftStruct *object, ThriftProtocol *protocol, GError **error)" << '\n'; } - indent(out) << "{" << endl; + indent(out) << "{" << '\n'; indent_up(); // declare stack temp variables - out << indent() << "gint32 ret;" << endl << indent() << "gint32 xfer = 0;" << endl << indent() - << "gchar *name = NULL;" << endl << indent() << "ThriftType ftype;" << endl << indent() - << "gint16 fid;" << endl << indent() << "guint32 len = 0;" << endl << indent() - << "gpointer data = NULL;" << endl << indent() << this_get << endl; + out << indent() << "gint32 ret;" << '\n' << indent() << "gint32 xfer = 0;" << '\n' << indent() + << "gchar *name = NULL;" << '\n' << indent() << "ThriftType ftype;" << '\n' << indent() + << "gint16 fid;" << '\n' << indent() << "guint32 len = 0;" << '\n' << indent() + << "gpointer data = NULL;" << '\n' << indent() << this_get << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if ((*f_iter)->get_req() == t_field::T_REQUIRED) { - indent(out) << "gboolean isset_" << (*f_iter)->get_name() << " = FALSE;" << endl; + indent(out) << "gboolean isset_" << (*f_iter)->get_name() << " = FALSE;" << '\n'; } } - out << endl; + out << '\n'; // satisfy -Wall in case we don't use some variables - out << indent() << "/* satisfy -Wall in case these aren't used */" << endl << indent() - << "THRIFT_UNUSED_VAR (len);" << endl << indent() << "THRIFT_UNUSED_VAR (data);" << endl; + out << indent() << "/* satisfy -Wall in case these aren't used */" << '\n' << indent() + << "THRIFT_UNUSED_VAR (len);" << '\n' << indent() << "THRIFT_UNUSED_VAR (data);" << '\n'; if (!this_get.empty()) { - out << indent() << "THRIFT_UNUSED_VAR (this_object);" << endl; + out << indent() << "THRIFT_UNUSED_VAR (this_object);" << '\n'; } - out << endl; + out << '\n'; // read the beginning of the structure marker - out << indent() << "/* read the struct begin marker */" << endl << indent() - << "if ((ret = thrift_protocol_read_struct_begin (protocol, &name, error)) < 0)" << endl - << indent() << "{" << endl << indent() << " if (name) g_free (name);" << endl << indent() - << " return " << error_ret << ";" << endl << indent() << "}" << endl << indent() - << "xfer += ret;" << endl << indent() << "if (name) g_free (name);" << endl << indent() - << "name = NULL;" << endl << endl; + out << indent() << "/* read the struct begin marker */" << '\n' << indent() + << "if ((ret = thrift_protocol_read_struct_begin (protocol, &name, error)) < 0)" << '\n' + << indent() << "{" << '\n' << indent() << " if (name) g_free (name);" << '\n' << indent() + << " return " << error_ret << ";" << '\n' << indent() << "}" << '\n' << indent() + << "xfer += ret;" << '\n' << indent() << "if (name) g_free (name);" << '\n' << indent() + << "name = NULL;" << '\n' << '\n'; // read the struct fields - out << indent() << "/* read the struct fields */" << endl << indent() << "while (1)" << endl; + out << indent() << "/* read the struct fields */" << '\n' << indent() << "while (1)" << '\n'; scope_up(out); // read beginning field marker - out << indent() << "/* read the beginning of a field */" << endl << indent() + out << indent() << "/* read the beginning of a field */" << '\n' << indent() << "if ((ret = thrift_protocol_read_field_begin (protocol, &name, &ftype, &fid, error)) < 0)" - << endl << indent() << "{" << endl << indent() << " if (name) g_free (name);" << endl - << indent() << " return " << error_ret << ";" << endl << indent() << "}" << endl << indent() - << "xfer += ret;" << endl << indent() << "if (name) g_free (name);" << endl << indent() - << "name = NULL;" << endl << endl; + << '\n' << indent() << "{" << '\n' << indent() << " if (name) g_free (name);" << '\n' + << indent() << " return " << error_ret << ";" << '\n' << indent() << "}" << '\n' << indent() + << "xfer += ret;" << '\n' << indent() << "if (name) g_free (name);" << '\n' << indent() + << "name = NULL;" << '\n' << '\n'; // check for field STOP marker - out << indent() << "/* break if we get a STOP field */" << endl << indent() - << "if (ftype == T_STOP)" << endl << indent() << "{" << endl << indent() << " break;" << endl - << indent() << "}" << endl << endl; + out << indent() << "/* break if we get a STOP field */" << '\n' << indent() + << "if (ftype == T_STOP)" << '\n' << indent() << "{" << '\n' << indent() << " break;" << '\n' + << indent() << "}" << '\n' << '\n'; // switch depending on the field type - indent(out) << "switch (fid)" << endl; + indent(out) << "switch (fid)" << '\n'; // start switch scope_up(out); // generate deserialization code for known types for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { - indent(out) << "case " << (*f_iter)->get_key() << ":" << endl; + indent(out) << "case " << (*f_iter)->get_key() << ":" << '\n'; indent_up(); - indent(out) << "if (ftype == " << type_to_enum((*f_iter)->get_type()) << ")" << endl; - indent(out) << "{" << endl; + indent(out) << "if (ftype == " << type_to_enum((*f_iter)->get_type()) << ")" << '\n'; + indent(out) << "{" << '\n'; indent_up(); // generate deserialize field generate_deserialize_field(out, *f_iter, this_name, "", error_ret, false); indent_down(); - out << indent() << "} else {" << endl << indent() - << " if ((ret = thrift_protocol_skip (protocol, ftype, error)) < 0)" << endl << indent() - << " return " << error_ret << ";" << endl << indent() << " xfer += ret;" << endl - << indent() << "}" << endl << indent() << "break;" << endl; + out << indent() << "} else {" << '\n' << indent() + << " if ((ret = thrift_protocol_skip (protocol, ftype, error)) < 0)" << '\n' << indent() + << " return " << error_ret << ";" << '\n' << indent() << " xfer += ret;" << '\n' + << indent() << "}" << '\n' << indent() << "break;" << '\n'; indent_down(); } // create the default case - out << indent() << "default:" << endl << indent() - << " if ((ret = thrift_protocol_skip (protocol, ftype, error)) < 0)" << endl << indent() - << " return " << error_ret << ";" << endl << indent() << " xfer += ret;" << endl - << indent() << " break;" << endl; + out << indent() << "default:" << '\n' << indent() + << " if ((ret = thrift_protocol_skip (protocol, ftype, error)) < 0)" << '\n' << indent() + << " return " << error_ret << ";" << '\n' << indent() << " xfer += ret;" << '\n' + << indent() << " break;" << '\n'; // end switch scope_down(out); // read field end marker - out << indent() << "if ((ret = thrift_protocol_read_field_end (protocol, error)) < 0)" << endl - << indent() << " return " << error_ret << ";" << endl << indent() << "xfer += ret;" << endl; + out << indent() << "if ((ret = thrift_protocol_read_field_end (protocol, error)) < 0)" << '\n' + << indent() << " return " << error_ret << ";" << '\n' << indent() << "xfer += ret;" << '\n'; // end while loop scope_down(out); - out << endl; + out << '\n'; // read the end of the structure - out << indent() << "if ((ret = thrift_protocol_read_struct_end (protocol, error)) < 0)" << endl - << indent() << " return " << error_ret << ";" << endl << indent() << "xfer += ret;" << endl - << endl; + out << indent() << "if ((ret = thrift_protocol_read_struct_end (protocol, error)) < 0)" << '\n' + << indent() << " return " << error_ret << ";" << '\n' << indent() << "xfer += ret;" << '\n' + << '\n'; // if a required field is missing, throw an error for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if ((*f_iter)->get_req() == t_field::T_REQUIRED) { - out << indent() << "if (!isset_" << (*f_iter)->get_name() << ")" << endl << indent() << "{" - << endl << indent() << " g_set_error (error, THRIFT_PROTOCOL_ERROR," << endl << indent() - << " THRIFT_PROTOCOL_ERROR_INVALID_DATA," << endl << indent() - << " \"missing field\");" << endl << indent() << " return -1;" << endl - << indent() << "}" << endl << endl; + out << indent() << "if (!isset_" << (*f_iter)->get_name() << ")" << '\n' << indent() << "{" + << '\n' << indent() << " g_set_error (error, THRIFT_PROTOCOL_ERROR," << '\n' << indent() + << " THRIFT_PROTOCOL_ERROR_INVALID_DATA," << '\n' << indent() + << " \"missing field\");" << '\n' << indent() << " return -1;" << '\n' + << indent() << "}" << '\n' << '\n'; } } if (is_function) { - indent(out) << "return xfer;" << endl; + indent(out) << "return xfer;" << '\n'; } // end the function/structure indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } void t_c_glib_generator::generate_serialize_field(ostream& out, @@ -3773,9 +3771,9 @@ void t_c_glib_generator::generate_serialize_field(ostream& out, } else { out << "i32 (protocol, (gint32) " << name; } - out << ", error)) < 0)" << endl - << indent() << " return " << error_ret << ";" << endl - << indent() << "xfer += ret;" << endl << endl; + out << ", error)) < 0)" << '\n' + << indent() << " return " << error_ret << ";" << '\n' + << indent() << "xfer += ret;" << '\n' << '\n'; } else { throw std::logic_error("DO NOT KNOW HOW TO SERIALIZE FIELD '" + name + "' TYPE '" + type_name(type)); @@ -3788,8 +3786,8 @@ void t_c_glib_generator::generate_serialize_struct(ostream& out, int error_ret) { (void)tstruct; out << indent() << "if ((ret = thrift_struct_write (THRIFT_STRUCT (" << prefix - << "), protocol, error)) < 0)" << endl << indent() << " return " << error_ret << ";" << endl - << indent() << "xfer += ret;" << endl << endl; + << "), protocol, error)) < 0)" << '\n' << indent() << " return " << error_ret << ";" << '\n' + << indent() << "xfer += ret;" << '\n' << '\n'; } void t_c_glib_generator::generate_serialize_container(ostream& out, @@ -3826,39 +3824,39 @@ void t_c_glib_generator::generate_serialize_container(ostream& out, * This is because we may exit early before we get a chance to free the * GList. */ - out << indent() << "GList *key_list = NULL, *iter = NULL;" << endl - << indent() << tkey_name << tkey_ptr << "* keys;" << endl - << indent() << "int i = 0, key_count;" << endl - << endl + out << indent() << "GList *key_list = NULL, *iter = NULL;" << '\n' + << indent() << tkey_name << tkey_ptr << "* keys;" << '\n' + << indent() << "int i = 0, key_count;" << '\n' + << '\n' << indent() << "if ((ret = thrift_protocol_write_map_begin (protocol, " << type_to_enum(tkey) << ", " << type_to_enum(tval) << ", " << prefix << " ? " << "(gint32) g_hash_table_size ((GHashTable *) " << prefix << ") : 0" - << ", error)) < 0)" << endl; + << ", error)) < 0)" << '\n'; indent_up(); - out << indent() << "return " << error_ret << ";" << endl; + out << indent() << "return " << error_ret << ";" << '\n'; indent_down(); - out << indent() << "xfer += ret;" << endl - << indent() << "if (" << prefix << ")" << endl + out << indent() << "xfer += ret;" << '\n' + << indent() << "if (" << prefix << ")" << '\n' << indent() << " g_hash_table_foreach ((GHashTable *) " << prefix - << ", thrift_hash_table_get_keys, &key_list);" << endl - << indent() << "key_count = g_list_length (key_list);" << endl + << ", thrift_hash_table_get_keys, &key_list);" << '\n' + << indent() << "key_count = g_list_length (key_list);" << '\n' << indent() << "keys = g_newa (" << tkey_name << tkey_ptr - << ", key_count);" << endl + << ", key_count);" << '\n' << indent() << "for (iter = g_list_first (key_list); iter; " - "iter = iter->next)" << endl; + "iter = iter->next)" << '\n'; indent_up(); out << indent() << "keys[i++] = (" << tkey_name << tkey_ptr - << ") iter->data;" << endl; + << ") iter->data;" << '\n'; indent_down(); - out << indent() << "g_list_free (key_list);" << endl - << endl - << indent() << "for (i = 0; i < key_count; ++i)" << endl; + out << indent() << "g_list_free (key_list);" << '\n' + << '\n' + << indent() << "for (i = 0; i < key_count; ++i)" << '\n'; scope_up(out); - out << indent() << keyname << " = keys[i];" << endl + out << indent() << keyname << " = keys[i];" << '\n' << indent() << valname << " = (" << tval_name << tval_ptr << ") g_hash_table_lookup (((GHashTable *) " << prefix - << "), (gpointer) " << keyname << ");" << endl - << endl; + << "), (gpointer) " << keyname << ");" << '\n' + << '\n'; generate_serialize_map_element(out, (t_map*)ttype, tkey_ptr + " " + keyname, @@ -3866,84 +3864,84 @@ void t_c_glib_generator::generate_serialize_container(ostream& out, error_ret); scope_down(out); out << indent() << "if ((ret = thrift_protocol_write_map_end (protocol, " - "error)) < 0)" << endl; + "error)) < 0)" << '\n'; indent_up(); - out << indent() << "return " << error_ret << ";" << endl; + out << indent() << "return " << error_ret << ";" << '\n'; indent_down(); - out << indent() << "xfer += ret;" << endl; + out << indent() << "xfer += ret;" << '\n'; } else if (ttype->is_set()) { t_type* telem = ((t_set*)ttype)->get_elem_type(); string telem_name = type_name(telem); string telem_ptr = telem->is_string() || !telem->is_base_type() ? "" : "*"; - out << indent() << "GList *key_list = NULL, *iter = NULL;" << endl - << indent() << telem_name << telem_ptr << "* keys;" << endl - << indent() << "int i = 0, key_count;" << endl - << indent() << telem_name << telem_ptr << " elem;" << endl - << indent() << "gpointer value;" << endl - << indent() << "THRIFT_UNUSED_VAR (value);" << endl - << endl + out << indent() << "GList *key_list = NULL, *iter = NULL;" << '\n' + << indent() << telem_name << telem_ptr << "* keys;" << '\n' + << indent() << "int i = 0, key_count;" << '\n' + << indent() << telem_name << telem_ptr << " elem;" << '\n' + << indent() << "gpointer value;" << '\n' + << indent() << "THRIFT_UNUSED_VAR (value);" << '\n' + << '\n' << indent() << "if ((ret = thrift_protocol_write_set_begin (protocol, " << type_to_enum(telem) << ", " << prefix << " ? " << "(gint32) g_hash_table_size ((GHashTable *) " << prefix << ") : 0" - << ", error)) < 0)" << endl; + << ", error)) < 0)" << '\n'; indent_up(); - out << indent() << "return " << error_ret << ";" << endl; + out << indent() << "return " << error_ret << ";" << '\n'; indent_down(); - out << indent() << "xfer += ret;" << endl - << indent() << "if (" << prefix << ")" << endl + out << indent() << "xfer += ret;" << '\n' + << indent() << "if (" << prefix << ")" << '\n' << indent() << " g_hash_table_foreach ((GHashTable *) " << prefix - << ", thrift_hash_table_get_keys, &key_list);" << endl - << indent() << "key_count = g_list_length (key_list);" << endl + << ", thrift_hash_table_get_keys, &key_list);" << '\n' + << indent() << "key_count = g_list_length (key_list);" << '\n' << indent() << "keys = g_newa (" << telem_name << telem_ptr - << ", key_count);" << endl + << ", key_count);" << '\n' << indent() << "for (iter = g_list_first (key_list); iter; " - "iter = iter->next)" << endl; + "iter = iter->next)" << '\n'; indent_up(); out << indent() << "keys[i++] = (" << telem_name << telem_ptr - << ") iter->data;" << endl; + << ") iter->data;" << '\n'; indent_down(); - out << indent() << "g_list_free (key_list);" << endl - << endl - << indent() << "for (i = 0; i < key_count; ++i)" << endl; + out << indent() << "g_list_free (key_list);" << '\n' + << '\n' + << indent() << "for (i = 0; i < key_count; ++i)" << '\n'; scope_up(out); - out << indent() << "elem = keys[i];" << endl + out << indent() << "elem = keys[i];" << '\n' << indent() << "value = (gpointer) g_hash_table_lookup " - "(((GHashTable *) " << prefix << "), (gpointer) elem);" << endl - << endl; + "(((GHashTable *) " << prefix << "), (gpointer) elem);" << '\n' + << '\n'; generate_serialize_set_element(out, (t_set*)ttype, telem_ptr + "elem", error_ret); scope_down(out); out << indent() << "if ((ret = thrift_protocol_write_set_end (protocol, " - "error)) < 0)" << endl; + "error)) < 0)" << '\n'; indent_up(); - out << indent() << "return " << error_ret << ";" << endl; + out << indent() << "return " << error_ret << ";" << '\n'; indent_down(); - out << indent() << "xfer += ret;" << endl; + out << indent() << "xfer += ret;" << '\n'; } else if (ttype->is_list()) { string length = "(" + prefix + " ? " + prefix + "->len : 0)"; string i = tmp("i"); - out << indent() << "guint " << i << ";" << endl - << endl + out << indent() << "guint " << i << ";" << '\n' + << '\n' << indent() << "if ((ret = thrift_protocol_write_list_begin (protocol, " << type_to_enum(((t_list*)ttype)->get_elem_type()) << ", (gint32) " - << length << ", error)) < 0)" << endl; + << length << ", error)) < 0)" << '\n'; indent_up(); - out << indent() << "return " << error_ret << ";" << endl; + out << indent() << "return " << error_ret << ";" << '\n'; indent_down(); - out << indent() << "xfer += ret;" << endl + out << indent() << "xfer += ret;" << '\n' << indent() << "for (" << i << " = 0; " << i << " < " << length << "; " - << i << "++)" << endl; + << i << "++)" << '\n'; scope_up(out); generate_serialize_list_element(out, (t_list*)ttype, prefix, i, error_ret); scope_down(out); out << indent() << "if ((ret = thrift_protocol_write_list_end (protocol, " - "error)) < 0)" << endl; + "error)) < 0)" << '\n'; indent_up(); - out << indent() << "return " << error_ret << ";" << endl; + out << indent() << "return " << error_ret << ";" << '\n'; indent_down(); - out << indent() << "xfer += ret;" << endl; + out << indent() << "xfer += ret;" << '\n'; } scope_down(out); @@ -4023,11 +4021,11 @@ void t_c_glib_generator::generate_deserialize_field(ostream& out, } else if (type->is_base_type()) { t_base_type::t_base tbase = ((t_base_type*)type)->get_base(); if (tbase == t_base_type::TYPE_STRING) { - indent(out) << "if (" << name << " != NULL)" << endl << indent() << "{" << endl; + indent(out) << "if (" << name << " != NULL)" << '\n' << indent() << "{" << '\n'; indent_up(); - indent(out) << "g_free(" << name << ");" << endl << indent() << name << " = NULL;" << endl; + indent(out) << "g_free(" << name << ");" << '\n' << indent() << name << " = NULL;" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } indent(out) << "if ((ret = thrift_protocol_read_"; @@ -4063,22 +4061,22 @@ void t_c_glib_generator::generate_deserialize_field(ostream& out, default: throw "compiler error: no C reader for base type " + t_base_type::t_base_name(tbase) + name; } - out << ", error)) < 0)" << endl; - out << indent() << " return " << error_ret << ";" << endl << indent() << "xfer += ret;" - << endl; + out << ", error)) < 0)" << '\n'; + out << indent() << " return " << error_ret << ";" << '\n' << indent() << "xfer += ret;" + << '\n'; // load the byte array with the data if (tbase == t_base_type::TYPE_STRING && type->is_binary()) { - indent(out) << name << " = g_byte_array_new();" << endl; - indent(out) << "g_byte_array_append (" << name << ", (guint8 *) data, (guint) len);" << endl; - indent(out) << "g_free (data);" << endl; + indent(out) << name << " = g_byte_array_new();" << '\n'; + indent(out) << "g_byte_array_append (" << name << ", (guint8 *) data, (guint) len);" << '\n'; + indent(out) << "g_free (data);" << '\n'; } } else if (type->is_enum()) { string t = tmp("ecast"); - out << indent() << "gint32 " << t << ";" << endl << indent() - << "if ((ret = thrift_protocol_read_i32 (protocol, &" << t << ", error)) < 0)" << endl - << indent() << " return " << error_ret << ";" << endl << indent() << "xfer += ret;" << endl - << indent() << name << " = (" << type_name(type) << ")" << t << ";" << endl; + out << indent() << "gint32 " << t << ";" << '\n' << indent() + << "if ((ret = thrift_protocol_read_i32 (protocol, &" << t << ", error)) < 0)" << '\n' + << indent() << " return " << error_ret << ";" << '\n' << indent() << "xfer += ret;" << '\n' + << indent() << name << " = (" << type_name(type) << ")" << t << ";" << '\n'; } else { throw std::logic_error("DO NOT KNOW HOW TO SERIALIZE FIELD '" + tfield->get_name() + "' TYPE '" + type_name(type)); @@ -4088,9 +4086,9 @@ void t_c_glib_generator::generate_deserialize_field(ostream& out, // set the isset variable. if the type is required, then set the // local variable indicating the value was set, so that we can do // validation later. if (prefix != "" && tfield->get_req() != t_field::T_REQUIRED) { - indent(out) << prefix << "__isset_" << tfield->get_name() << suffix << " = TRUE;" << endl; + indent(out) << prefix << "__isset_" << tfield->get_name() << suffix << " = TRUE;" << '\n'; } else if (prefix != "" && tfield->get_req() == t_field::T_REQUIRED) { - indent(out) << "isset_" << tfield->get_name() << " = TRUE;" << endl; + indent(out) << "isset_" << tfield->get_name() << " = TRUE;" << '\n'; } } @@ -4101,30 +4099,30 @@ void t_c_glib_generator::generate_deserialize_struct(ostream& out, bool allocate) { string name_uc = to_upper_case(initial_caps_to_underscores(tstruct->get_name())); if (tstruct->is_xception()) { - out << indent() << "/* This struct is an exception */" << endl; + out << indent() << "/* This struct is an exception */" << '\n'; allocate = true; } if (allocate) { - out << indent() << "if ( " << prefix << " != NULL)" << endl << indent() << "{" << endl; + out << indent() << "if ( " << prefix << " != NULL)" << '\n' << indent() << "{" << '\n'; indent_up(); - out << indent() << "g_object_unref (" << prefix << ");" << endl; + out << indent() << "g_object_unref (" << prefix << ");" << '\n'; indent_down(); - out << indent() << "}" << endl << indent() << prefix << " = g_object_new (" << this->nspace_uc - << "TYPE_" << name_uc << ", NULL);" << endl; + out << indent() << "}" << '\n' << indent() << prefix << " = g_object_new (" << this->nspace_uc + << "TYPE_" << name_uc << ", NULL);" << '\n'; } out << indent() << "if ((ret = thrift_struct_read (THRIFT_STRUCT (" << prefix - << "), protocol, error)) < 0)" << endl << indent() << "{" << endl; + << "), protocol, error)) < 0)" << '\n' << indent() << "{" << '\n'; indent_up(); if (allocate) { - indent(out) << "g_object_unref (" << prefix << ");" << endl; + indent(out) << "g_object_unref (" << prefix << ");" << '\n'; if (tstruct->is_xception()) { - indent(out) << prefix << " = NULL;" << endl; + indent(out) << prefix << " = NULL;" << '\n'; } } - out << indent() << "return " << error_ret << ";" << endl; + out << indent() << "return " << error_ret << ";" << '\n'; indent_down(); - out << indent() << "}" << endl << indent() << "xfer += ret;" << endl; + out << indent() << "}" << '\n' << indent() << "xfer += ret;" << '\n'; } void t_c_glib_generator::generate_deserialize_container(ostream& out, @@ -4134,80 +4132,80 @@ void t_c_glib_generator::generate_deserialize_container(ostream& out, scope_up(out); if (ttype->is_map()) { - out << indent() << "guint32 size;" << endl - << indent() << "guint32 i;" << endl - << indent() << "ThriftType key_type;" << endl - << indent() << "ThriftType value_type;" << endl - << endl - << indent() << "/* read the map begin marker */" << endl + out << indent() << "guint32 size;" << '\n' + << indent() << "guint32 i;" << '\n' + << indent() << "ThriftType key_type;" << '\n' + << indent() << "ThriftType value_type;" << '\n' + << '\n' + << indent() << "/* read the map begin marker */" << '\n' << indent() << "if ((ret = thrift_protocol_read_map_begin (protocol, " - "&key_type, &value_type, &size, error)) < 0)" << endl; + "&key_type, &value_type, &size, error)) < 0)" << '\n'; indent_up(); - out << indent() << "return " << error_ret << ";" << endl; + out << indent() << "return " << error_ret << ";" << '\n'; indent_down(); - out << indent() << "xfer += ret;" << endl - << endl; + out << indent() << "xfer += ret;" << '\n' + << '\n'; // iterate over map elements - out << indent() << "/* iterate through each of the map's fields */" << endl - << indent() << "for (i = 0; i < size; i++)" << endl; + out << indent() << "/* iterate through each of the map's fields */" << '\n' + << indent() << "for (i = 0; i < size; i++)" << '\n'; scope_up(out); generate_deserialize_map_element(out, (t_map*)ttype, prefix, error_ret); scope_down(out); - out << endl; + out << '\n'; // read map end - out << indent() << "/* read the map end marker */" << endl + out << indent() << "/* read the map end marker */" << '\n' << indent() << "if ((ret = thrift_protocol_read_map_end (protocol, " - "error)) < 0)" << endl; + "error)) < 0)" << '\n'; indent_up(); - out << indent() << "return " << error_ret << ";" << endl; + out << indent() << "return " << error_ret << ";" << '\n'; indent_down(); - out << indent() << "xfer += ret;" << endl; + out << indent() << "xfer += ret;" << '\n'; } else if (ttype->is_set()) { - out << indent() << "guint32 size;" << endl - << indent() << "guint32 i;" << endl - << indent() << "ThriftType element_type;" << endl - << endl + out << indent() << "guint32 size;" << '\n' + << indent() << "guint32 i;" << '\n' + << indent() << "ThriftType element_type;" << '\n' + << '\n' << indent() << "if ((ret = thrift_protocol_read_set_begin (protocol, " - "&element_type, &size, error)) < 0)" << endl; + "&element_type, &size, error)) < 0)" << '\n'; indent_up(); - out << indent() << "return " << error_ret << ";" << endl; + out << indent() << "return " << error_ret << ";" << '\n'; indent_down(); - out << indent() << "xfer += ret;" << endl - << endl; + out << indent() << "xfer += ret;" << '\n' + << '\n'; // iterate over the elements - out << indent() << "/* iterate through the set elements */" << endl - << indent() << "for (i = 0; i < size; ++i)" << endl; + out << indent() << "/* iterate through the set elements */" << '\n' + << indent() << "for (i = 0; i < size; ++i)" << '\n'; scope_up(out); generate_deserialize_set_element(out, (t_set*)ttype, prefix, error_ret); scope_down(out); // read set end out << indent() << "if ((ret = thrift_protocol_read_set_end (protocol, " - "error)) < 0)" << endl; + "error)) < 0)" << '\n'; indent_up(); - out << indent() << "return " << error_ret << ";" << endl; + out << indent() << "return " << error_ret << ";" << '\n'; indent_down(); - out << indent() << "xfer += ret;" << endl - << endl; + out << indent() << "xfer += ret;" << '\n' + << '\n'; } else if (ttype->is_list()) { - out << indent() << "guint32 size;" << endl - << indent() << "guint32 i;" << endl - << indent() << "ThriftType element_type;" << endl - << endl + out << indent() << "guint32 size;" << '\n' + << indent() << "guint32 i;" << '\n' + << indent() << "ThriftType element_type;" << '\n' + << '\n' << indent() << "if ((ret = thrift_protocol_read_list_begin (protocol, " - "&element_type,&size, error)) < 0)" << endl; + "&element_type,&size, error)) < 0)" << '\n'; indent_up(); - out << indent() << "return " << error_ret << ";" << endl; + out << indent() << "return " << error_ret << ";" << '\n'; indent_down(); - out << indent() << "xfer += ret;" << endl - << endl; + out << indent() << "xfer += ret;" << '\n' + << '\n'; // iterate over the elements - out << indent() << "/* iterate through list elements */" << endl - << indent() << "for (i = 0; i < size; i++)" << endl; + out << indent() << "/* iterate through list elements */" << '\n' + << indent() << "for (i = 0; i < size; i++)" << '\n'; scope_up(out); generate_deserialize_list_element(out, (t_list*)ttype, @@ -4218,11 +4216,11 @@ void t_c_glib_generator::generate_deserialize_container(ostream& out, // read list end out << indent() << "if ((ret = thrift_protocol_read_list_end (protocol, " - "error)) < 0)" << endl; + "error)) < 0)" << '\n'; indent_up(); - out << indent() << "return " << error_ret << ";" << endl; + out << indent() << "return " << error_ret << ";" << '\n'; indent_down(); - out << indent() << "xfer += ret;" << endl; + out << indent() << "xfer += ret;" << '\n'; } scope_down(out); @@ -4239,16 +4237,16 @@ void t_c_glib_generator::declare_local_variable(ostream& out, t_type* ttype, str if (ttype->is_map()) { t_map* tmap = (t_map*)ttype; out << indent() << tname << ptr << " " << name << " = " - << generate_new_hash_from_type(tmap->get_key_type(), tmap->get_val_type()) << endl; + << generate_new_hash_from_type(tmap->get_key_type(), tmap->get_val_type()) << '\n'; } else if (ttype->is_list()) { t_list* tlist = (t_list*)ttype; out << indent() << tname << ptr << " " << name << " = " - << generate_new_array_from_type(tlist->get_elem_type()) << endl; + << generate_new_array_from_type(tlist->get_elem_type()) << '\n'; } else if (for_hash_table && ttype->is_enum()) { - out << indent() << tname << " " << name << ";" << endl; + out << indent() << tname << " " << name << ";" << '\n'; } else { out << indent() << tname << ptr << " " << name - << (ptr != "" ? " = g_new (" + tname + ", 1)" : " = NULL") << ";" << endl; + << (ptr != "" ? " = g_new (" + tname + ", 1)" : " = NULL") << ";" << '\n'; } } @@ -4259,7 +4257,7 @@ void t_c_glib_generator::declore_local_variable_for_write(ostream& out, ttype = get_true_type(ttype); string ptr = ttype->is_string() || !ttype->is_base_type() ? " " : "* "; string init_val = ttype->is_enum() ? "" : " = NULL"; - out << indent() << tname << ptr << name << init_val << ";" << endl; + out << indent() << tname << ptr << name << init_val << ";" << '\n'; } void t_c_glib_generator::generate_deserialize_map_element(ostream& out, @@ -4289,10 +4287,10 @@ void t_c_glib_generator::generate_deserialize_map_element(ostream& out, t_field fval(tval, tval_ptr + valname); generate_deserialize_field(out, &fval, "", "", error_ret); - indent(out) << "if (" << prefix << " && " << keyname << ")" << endl; + indent(out) << "if (" << prefix << " && " << keyname << ")" << '\n'; indent_up(); indent(out) << "g_hash_table_insert ((GHashTable *)" << prefix << ", (gpointer) " << keyname - << ", (gpointer) " << valname << ");" << endl; + << ", (gpointer) " << valname << ");" << '\n'; indent_down(); } @@ -4309,10 +4307,10 @@ void t_c_glib_generator::generate_deserialize_set_element(ostream& out, t_field felem(telem, telem_ptr + elem); generate_deserialize_field(out, &felem, "", "", error_ret); - indent(out) << "if (" << prefix << " && " << elem << ")" << endl; + indent(out) << "if (" << prefix << " && " << elem << ")" << '\n'; indent_up(); indent(out) << "g_hash_table_insert ((GHashTable *) " << prefix << ", (gpointer) " << elem - << ", (gpointer) " << elem << ");" << endl; + << ", (gpointer) " << elem << ");" << '\n'; indent_down(); } @@ -4334,10 +4332,10 @@ void t_c_glib_generator::generate_deserialize_list_element(ostream& out, if (ttype->is_void()) { throw std::runtime_error("compiler error: list element type cannot be void"); } else if (is_numeric(ttype)) { - indent(out) << "g_array_append_vals (" << prefix << ", " << elem << ", 1);" << endl; - indent(out) << "g_free (" << elem << ");" << endl; + indent(out) << "g_array_append_vals (" << prefix << ", " << elem << ", 1);" << '\n'; + indent(out) << "g_free (" << elem << ");" << '\n'; } else { - indent(out) << "g_ptr_array_add (" << prefix << ", " << elem << ");" << endl; + indent(out) << "g_ptr_array_add (" << prefix << ", " << elem << ");" << '\n'; } } diff --git a/compiler/cpp/src/thrift/generate/t_cl_generator.cc b/compiler/cpp/src/thrift/generate/t_cl_generator.cc index e0dcc46af4b..409af1dd174 100644 --- a/compiler/cpp/src/thrift/generate/t_cl_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_cl_generator.cc @@ -60,7 +60,7 @@ class t_cl_generator : public t_oop_generator { if(iter->first.compare("no_asd") == 0) { no_asd = true; } else if (iter->first.compare("sys_pref") == 0) { - system_prefix = iter->second; + system_prefix = iter->second; } else { throw "unknown option cl:" + iter->first; } @@ -130,9 +130,9 @@ void t_cl_generator::init_generator() { string f_vars_name = program_dir + "/" + program_name_ + "-vars.lisp"; f_types_.open(f_types_name); - f_types_ << cl_autogen_comment() << endl; + f_types_ << cl_autogen_comment() << '\n'; f_vars_.open(f_vars_name); - f_vars_ << cl_autogen_comment() << endl; + f_vars_ << cl_autogen_comment() << '\n'; package_def(f_types_); package_in(f_types_); @@ -141,7 +141,7 @@ void t_cl_generator::init_generator() { if (!no_asd) { string f_asd_name = program_dir + "/" + system_prefix + program_name_ + ".asd"; f_asd_.open(f_asd_name); - f_asd_ << cl_autogen_comment() << endl; + f_asd_ << cl_autogen_comment() << '\n'; asdf_def(f_asd_); } } @@ -197,13 +197,13 @@ string t_cl_generator::generated_package() { } void t_cl_generator::asdf_def(std::ostream &out) { - out << "(asdf:defsystem #:" << system_prefix << program_name_ << endl; + out << "(asdf:defsystem #:" << system_prefix << program_name_ << '\n'; indent_up(); out << indent() << render_includes() - << indent() << ":serial t" << endl + << indent() << ":serial t" << '\n' << indent() << ":components (" << "(:file \"" << program_name_ << "-types\") " - << "(:file \"" << program_name_ << "-vars\")))" << endl; + << "(:file \"" << program_name_ << "-vars\")))" << '\n'; indent_down(); } @@ -221,11 +221,11 @@ void t_cl_generator::package_def(std::ostream &out) { } out << ")"; } - out << ")" << endl << endl; + out << ")" << '\n' << '\n'; } void t_cl_generator::package_in(std::ostream &out) { - out << "(cl:in-package :" << package() << ")" << endl << endl; + out << "(cl:in-package :" << package() << ")" << '\n' << '\n'; } /** @@ -238,7 +238,7 @@ void t_cl_generator::generate_typedef(t_typedef* ttypedef) { } void t_cl_generator::generate_enum(t_enum* tenum) { - f_types_ << "(thrift:def-enum " << prefix(tenum->get_name()) << endl; + f_types_ << "(thrift:def-enum " << prefix(tenum->get_name()) << '\n'; vector constants = tenum->get_constants(); vector::iterator c_iter; @@ -249,12 +249,12 @@ void t_cl_generator::generate_enum(t_enum* tenum) { for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) { value = (*c_iter)->get_value(); - if(c_iter != constants.begin()) f_types_ << endl << indent() << " "; + if(c_iter != constants.begin()) f_types_ << '\n' << indent() << " "; f_types_ << "(\"" << (*c_iter)->get_name() << "\" . " << value << ")"; } indent_down(); - f_types_ << "))" << endl << endl; + f_types_ << "))" << '\n' << '\n'; } /** @@ -266,7 +266,7 @@ void t_cl_generator::generate_const(t_const* tconst) { t_const_value* value = tconst->get_value(); f_vars_ << "(thrift:def-constant " << prefix(name) << " " << render_const_value(type, value) << ")" - << endl << endl; + << '\n' << '\n'; } /** @@ -306,7 +306,7 @@ string t_cl_generator::render_const_value(t_type* type, t_const_value* value) { indent(out) << value->get_integer(); } else if (type->is_struct() || type->is_xception()) { out << (type->is_struct() ? "(make-instance '" : "(make-exception '") << - lowercase(type->get_name()) << " " << endl; + lowercase(type->get_name()) << " " << '\n'; indent_up(); const vector& fields = ((t_struct*)type)->get_members(); @@ -326,7 +326,7 @@ string t_cl_generator::render_const_value(t_type* type, t_const_value* value) { } out << indent() << ":" << v_iter->first->get_string() << " " << - render_const_value(field_type, v_iter->second) << endl; + render_const_value(field_type, v_iter->second) << '\n'; } out << indent() << ")"; @@ -340,7 +340,7 @@ string t_cl_generator::render_const_value(t_type* type, t_const_value* value) { const map& val = value->get_map(); map::const_iterator v_iter; for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { - out << endl << indent() + out << '\n' << indent() << "(cl:cons " << render_const_value(ktype, v_iter->first) << " " << render_const_value(vtype, v_iter->second) << ")"; } @@ -354,16 +354,16 @@ string t_cl_generator::render_const_value(t_type* type, t_const_value* value) { etype = ((t_set*)type)->get_elem_type(); } if (type->is_set()) { - out << "(thrift:set" << endl; + out << "(thrift:set" << '\n'; } else { - out << "(thrift:list" << endl; + out << "(thrift:list" << '\n'; } indent_up(); indent_up(); const vector& val = value->get_list(); vector::const_iterator v_iter; for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { - out << indent() << render_const_value(etype, *v_iter) << endl; + out << indent() << render_const_value(etype, *v_iter) << '\n'; } out << indent() << ")"; indent_down(); @@ -394,7 +394,7 @@ void t_cl_generator::generate_cl_struct_internal(std::ostream& out, t_struct* ts t_type* type = (*m_iter)->get_type(); if (m_iter != members.begin()) { - out << endl << indent() << " "; + out << '\n' << indent() << " "; } out << "(" << prefix((*m_iter)->get_name()) << " " << ( (nullptr != value) ? render_const_value(type, value) : "nil" ) << @@ -421,16 +421,16 @@ void t_cl_generator::generate_cl_struct_internal(std::ostream& out, t_struct* ts void t_cl_generator::generate_cl_struct(std::ostream& out, t_struct* tstruct, bool is_exception = false) { std::string name = type_name(tstruct); out << (is_exception ? "(thrift:def-exception " : "(thrift:def-struct ") << - prefix(name) << endl; + prefix(name) << '\n'; indent_up(); if ( tstruct->has_doc() ) { out << indent() ; - out << "\"" << cl_docstring(tstruct->get_doc()) << "\"" << endl; + out << "\"" << cl_docstring(tstruct->get_doc()) << "\"" << '\n'; } out << indent() ; generate_cl_struct_internal(out, tstruct, is_exception); indent_down(); - out << ")" << endl << endl; + out << ")" << '\n' << '\n'; } void t_cl_generator::generate_exception_sig(std::ostream& out, t_function* f) { @@ -454,7 +454,7 @@ void t_cl_generator::generate_service(t_service* tservice) { indent_up(); if ( tservice->has_doc()) { - f_types_ << endl << indent() + f_types_ << '\n' << indent() << "(:documentation \"" << cl_docstring(tservice->get_doc()) << "\")"; } @@ -465,23 +465,23 @@ void t_cl_generator::generate_service(t_service* tservice) { t_struct* exceptions = function->get_xceptions(); const vector& xmembers = exceptions->get_members(); - f_types_ << endl << indent() << "(:method " << prefix(fname); + f_types_ << '\n' << indent() << "(:method " << prefix(fname); f_types_ << " (" << signature << " " << typespec((*f_iter)->get_returntype()) << ")"; if (xmembers.size() > 0) { - f_types_ << endl << indent() << " :exceptions " ; + f_types_ << '\n' << indent() << " :exceptions " ; generate_exception_sig(f_types_, function); } if ( (*f_iter)->is_oneway() ) { - f_types_ << endl << indent() << " :oneway t"; + f_types_ << '\n' << indent() << " :oneway t"; } if ( (*f_iter)->has_doc() ) { - f_types_ << endl << indent() << " :documentation \"" + f_types_ << '\n' << indent() << " :documentation \"" << cl_docstring((*f_iter)->get_doc()) << "\""; } f_types_ << ")"; } - f_types_ << ")" << endl << endl; + f_types_ << ")" << '\n' << '\n'; indent_down(); } diff --git a/compiler/cpp/src/thrift/generate/t_cpp_generator.cc b/compiler/cpp/src/thrift/generate/t_cpp_generator.cc index 9724fae80a6..5777b278421 100644 --- a/compiler/cpp/src/thrift/generate/t_cpp_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_cpp_generator.cc @@ -42,8 +42,6 @@ using std::ostream; using std::string; using std::vector; -static const string endl = "\n"; // avoid ostream << std::endl flushes - /** * C++ code generator. This is legitimacy incarnate. * @@ -68,6 +66,7 @@ class t_cpp_generator : public t_oop_generator { gen_moveable_ = false; gen_no_ostream_operators_ = false; gen_no_skeleton_ = false; + gen_no_constructors_ = false; has_members_ = false; for( iter = parsed_options.begin(); iter != parsed_options.end(); ++iter) { @@ -90,6 +89,8 @@ class t_cpp_generator : public t_oop_generator { gen_no_ostream_operators_ = true; } else if ( iter->first.compare("no_skeleton") == 0) { gen_no_skeleton_ = true; + } else if ( iter->first.compare("no_constructors") == 0) { + gen_no_constructors_ = true; } else { throw "unknown option cpp:" + iter->first; } @@ -126,7 +127,7 @@ class t_cpp_generator : public t_oop_generator { 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, + std::string render_const_value(std::ostream* out, std::string name, t_type* type, t_const_value* value); @@ -143,14 +144,17 @@ class t_cpp_generator : public t_oop_generator { std::ostream& force_cpp_out, t_struct* tstruct, bool setters = true, - bool is_user_struct = false); + bool is_user_struct = false, + bool pointers = false); void generate_copy_constructor(std::ostream& out, t_struct* tstruct, bool is_exception); void generate_move_constructor(std::ostream& out, t_struct* tstruct, bool is_exception); + void generate_default_constructor(std::ostream& out, t_struct* tstruct, bool is_exception); void generate_constructor_helper(std::ostream& out, t_struct* tstruct, bool is_excpetion, bool is_move); void generate_assignment_operator(std::ostream& out, t_struct* tstruct); + void generate_equality_operator(std::ostream& out, t_struct* tstruct); void generate_move_assignment_operator(std::ostream& out, t_struct* tstruct); void generate_assignment_helper(std::ostream& out, t_struct* tstruct, bool is_move); void generate_struct_reader(std::ostream& out, t_struct* tstruct, bool pointers = false); @@ -270,9 +274,12 @@ class t_cpp_generator : public t_oop_generator { bool is_complex_type(t_type* ttype) { ttype = get_true_type(ttype); - return ttype->is_container() || ttype->is_struct() || ttype->is_xception() + return ttype->is_container() // + || ttype->is_struct() // + || ttype->is_xception() || (ttype->is_base_type() - && (((t_base_type*)ttype)->get_base() == t_base_type::TYPE_STRING)); + && ((((t_base_type*)ttype)->get_base() == t_base_type::TYPE_STRING) + || (((t_base_type*)ttype)->get_base() == t_base_type::TYPE_UUID))); } void set_use_include_prefix(bool use_include_prefix) { use_include_prefix_ = use_include_prefix; } @@ -293,13 +300,19 @@ class t_cpp_generator : public t_oop_generator { (ttype->annotations_.find("cpp.customostream") != ttype->annotations_.end()); } - /** + /** * Determine if all fields of t_struct's storage do not throw * Move/Copy Constructors and Assignments applicable for 'noexcept' * Move defaults to 'noexcept' */ bool is_struct_storage_not_throwing(t_struct* tstruct) const; + /** + * Helper function to determine whether any of the members of our struct + * has a default value. + */ + bool has_field_with_default_value(t_struct* tstruct); + private: /** * Returns the include prefix to use for a file generated by program, or the @@ -309,7 +322,7 @@ class t_cpp_generator : public t_oop_generator { /** * Returns the legal program name to use for a file generated by program, if the - * program name contains dots then replace it with underscores, otherwise return the + * program name contains dots then replace it with underscores, otherwise return the * original program name. */ std::string get_legal_program_name(std::string program_name); @@ -362,10 +375,15 @@ class t_cpp_generator : public t_oop_generator { bool gen_no_default_operators_; /** - * True if we should generate skeleton. + * True if we should omit generating skeleton. */ bool gen_no_skeleton_; + /** + * True if we should omit generating constructors/destructors/assignment/destructors. + */ + bool gen_no_constructors_; + /** * True if thrift has member(s) */ @@ -429,69 +447,69 @@ void t_cpp_generator::init_generator() { f_types_tcc_ << autogen_comment(); // Start ifndef - f_types_ << "#ifndef " << program_name_ << "_TYPES_H" << endl << "#define " << program_name_ - << "_TYPES_H" << endl << endl; - f_types_tcc_ << "#ifndef " << program_name_ << "_TYPES_TCC" << endl << "#define " << program_name_ - << "_TYPES_TCC" << endl << endl; + f_types_ << "#ifndef " << program_name_ << "_TYPES_H" << '\n' << "#define " << program_name_ + << "_TYPES_H" << '\n' << '\n'; + f_types_tcc_ << "#ifndef " << program_name_ << "_TYPES_TCC" << '\n' << "#define " << program_name_ + << "_TYPES_TCC" << '\n' << '\n'; // Include base types - f_types_ << "#include " << endl - << endl - << "#include " << endl - << "#include " << endl - << "#include " << endl - << "#include " << endl - << "#include " << endl - << endl; + f_types_ << "#include " << '\n' + << '\n' + << "#include " << '\n' + << "#include " << '\n' + << "#include " << '\n' + << "#include " << '\n' + << "#include " << '\n' + << '\n'; // Include C++xx compatibility header - f_types_ << "#include " << endl; - f_types_ << "#include " << endl; + f_types_ << "#include " << '\n'; + f_types_ << "#include " << '\n'; // Include other Thrift includes const vector& includes = program_->get_includes(); for (auto include : includes) { f_types_ << "#include \"" << get_include_prefix(*include) << include->get_name() - << "_types.h\"" << endl; + << "_types.h\"" << '\n'; // 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(*include) << include->get_name() - << "_types.tcc\"" << endl; + << "_types.tcc\"" << '\n'; } - f_types_ << endl; + f_types_ << '\n'; // Include custom headers const vector& cpp_includes = program_->get_cpp_includes(); for (const auto & cpp_include : cpp_includes) { if (cpp_include[0] == '<') { - f_types_ << "#include " << cpp_include << endl; + f_types_ << "#include " << cpp_include << '\n'; } else { - f_types_ << "#include \"" << cpp_include << "\"" << endl; + f_types_ << "#include \"" << cpp_include << "\"" << '\n'; } } - f_types_ << endl; + f_types_ << '\n'; // Include the types file f_types_impl_ << "#include \"" << get_include_prefix(*get_program()) << program_name_ - << "_types.h\"" << endl << endl; + << "_types.h\"" << '\n' << '\n'; f_types_tcc_ << "#include \"" << get_include_prefix(*get_program()) << program_name_ - << "_types.h\"" << endl << endl; + << "_types.h\"" << '\n' << '\n'; // The swap() code needs for std::swap() - f_types_impl_ << "#include " << endl; + f_types_impl_ << "#include " << '\n'; // for operator<< - f_types_impl_ << "#include " << endl << endl; - f_types_impl_ << "#include " << endl << endl; + f_types_impl_ << "#include " << '\n' << '\n'; + f_types_impl_ << "#include " << '\n' << '\n'; // Open namespace ns_open_ = namespace_open(program_->get_namespace("cpp")); ns_close_ = namespace_close(program_->get_namespace("cpp")); - f_types_ << ns_open_ << endl << endl; + f_types_ << ns_open_ << '\n' << '\n'; - f_types_impl_ << ns_open_ << endl << endl; + f_types_impl_ << ns_open_ << '\n' << '\n'; - f_types_tcc_ << ns_open_ << endl << endl; + f_types_tcc_ << ns_open_ << '\n' << '\n'; } /** @@ -499,21 +517,21 @@ void t_cpp_generator::init_generator() { */ void t_cpp_generator::close_generator() { // Close namespace - f_types_ << ns_close_ << endl << endl; - f_types_impl_ << ns_close_ << endl; - f_types_tcc_ << ns_close_ << endl << endl; + f_types_ << ns_close_ << '\n' << '\n'; + f_types_impl_ << ns_close_ << '\n'; + f_types_tcc_ << ns_close_ << '\n' << '\n'; // Include the types.tcc file from the types header file, // so clients don't have to explicitly include the tcc file. // TODO(simpkins): Make this a separate option. if (gen_templates_) { f_types_ << "#include \"" << get_include_prefix(*get_program()) << program_name_ - << "_types.tcc\"" << endl << endl; + << "_types.tcc\"" << '\n' << '\n'; } // Close ifndef - f_types_ << "#endif" << endl; - f_types_tcc_ << "#endif" << endl; + f_types_ << "#endif" << '\n'; + f_types_tcc_ << "#endif" << '\n'; // Close output file f_types_.close(); @@ -535,7 +553,7 @@ void t_cpp_generator::close_generator() { void t_cpp_generator::generate_typedef(t_typedef* ttypedef) { generate_java_doc(f_types_, ttypedef); f_types_ << indent() << "typedef " << type_name(ttypedef->get_type(), true) << " " - << ttypedef->get_symbolic() << ";" << endl << endl; + << ttypedef->get_symbolic() << ";" << '\n' << '\n'; } void t_cpp_generator::generate_enum_constant_list(std::ostream& f, @@ -543,7 +561,7 @@ void t_cpp_generator::generate_enum_constant_list(std::ostream& f, const char* prefix, const char* suffix, bool include_values) { - f << " {" << endl; + f << " {" << '\n'; indent_up(); vector::const_iterator c_iter; @@ -552,7 +570,7 @@ void t_cpp_generator::generate_enum_constant_list(std::ostream& f, if (first) { first = false; } else { - f << "," << endl; + f << "," << '\n'; } generate_java_doc(f, *c_iter); indent(f) << prefix << (*c_iter)->get_name() << suffix; @@ -561,9 +579,9 @@ void t_cpp_generator::generate_enum_constant_list(std::ostream& f, } } - f << endl; + f << '\n'; indent_down(); - indent(f) << "};" << endl; + indent(f) << "};" << '\n'; } /** @@ -579,7 +597,7 @@ void t_cpp_generator::generate_enum(t_enum* tenum) { if (!gen_pure_enums_) { enum_name = "type"; generate_java_doc(f_types_, tenum); - f_types_ << indent() << "struct " << tenum->get_name() << " {" << endl; + f_types_ << indent() << "struct " << tenum->get_name() << " {" << '\n'; indent_up(); } f_types_ << indent() << "enum " << enum_name; @@ -588,10 +606,10 @@ void t_cpp_generator::generate_enum(t_enum* tenum) { if (!gen_pure_enums_) { indent_down(); - f_types_ << "};" << endl; + f_types_ << "};" << '\n'; } - f_types_ << endl; + f_types_ << '\n'; /** Generate a character array of enum names for debugging purposes. @@ -608,13 +626,13 @@ void t_cpp_generator::generate_enum(t_enum* tenum) { generate_enum_constant_list(f_types_impl_, constants, "\"", "\"", false); f_types_ << indent() << "extern const std::map _" << tenum->get_name() - << "_VALUES_TO_NAMES;" << endl << endl; + << "_VALUES_TO_NAMES;" << '\n' << '\n'; f_types_impl_ << indent() << "const std::map _" << tenum->get_name() << "_VALUES_TO_NAMES(::apache::thrift::TEnumIterator(" << constants.size() << ", _k" << tenum->get_name() << "Values" << ", _k" << tenum->get_name() << "Names), " - << "::apache::thrift::TEnumIterator(-1, nullptr, nullptr));" << endl << endl; + << "::apache::thrift::TEnumIterator(-1, nullptr, nullptr));" << '\n' << '\n'; generate_enum_ostream_operator_decl(f_types_, tenum); generate_enum_ostream_operator(f_types_impl_, tenum); @@ -633,8 +651,8 @@ void t_cpp_generator::generate_enum_ostream_operator_decl(std::ostream& out, t_e } else { out << tenum->get_name() << "::type&"; } - out << " val);" << endl; - out << endl; + out << " val);" << '\n'; + out << '\n'; } void t_cpp_generator::generate_enum_ostream_operator(std::ostream& out, t_enum* tenum) { @@ -653,20 +671,20 @@ void t_cpp_generator::generate_enum_ostream_operator(std::ostream& out, t_enum* scope_up(out); out << indent() << "std::map::const_iterator it = _" - << tenum->get_name() << "_VALUES_TO_NAMES.find(val);" << endl; - out << indent() << "if (it != _" << tenum->get_name() << "_VALUES_TO_NAMES.end()) {" << endl; + << tenum->get_name() << "_VALUES_TO_NAMES.find(val);" << '\n'; + out << indent() << "if (it != _" << tenum->get_name() << "_VALUES_TO_NAMES.end()) {" << '\n'; indent_up(); - out << indent() << "out << it->second;" << endl; + out << indent() << "out << it->second;" << '\n'; indent_down(); - out << indent() << "} else {" << endl; + out << indent() << "} else {" << '\n'; indent_up(); - out << indent() << "out << static_cast(val);" << endl; + out << indent() << "out << static_cast(val);" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; - out << indent() << "return out;" << endl; + out << indent() << "return out;" << '\n'; scope_down(out); - out << endl; + out << '\n'; } } @@ -677,8 +695,8 @@ void t_cpp_generator::generate_enum_to_string_helper_function_decl(std::ostream& } else { out << tenum->get_name() << "::type&"; } - out << " val);" << endl; - out << endl; + out << " val);" << '\n'; + out << '\n'; } void t_cpp_generator::generate_enum_to_string_helper_function(std::ostream& out, t_enum* tenum) { @@ -693,19 +711,19 @@ void t_cpp_generator::generate_enum_to_string_helper_function(std::ostream& out, scope_up(out); out << indent() << "std::map::const_iterator it = _" - << tenum->get_name() << "_VALUES_TO_NAMES.find(val);" << endl; - out << indent() << "if (it != _" << tenum->get_name() << "_VALUES_TO_NAMES.end()) {" << endl; + << tenum->get_name() << "_VALUES_TO_NAMES.find(val);" << '\n'; + out << indent() << "if (it != _" << tenum->get_name() << "_VALUES_TO_NAMES.end()) {" << '\n'; indent_up(); - out << indent() << "return std::string(it->second);" << endl; + out << indent() << "return std::string(it->second);" << '\n'; indent_down(); - out << indent() << "} else {" << endl; + out << indent() << "} else {" << '\n'; indent_up(); - out << indent() << "return std::to_string(static_cast(val));" << endl; + out << indent() << "return std::to_string(static_cast(val));" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; scope_down(out); - out << endl; + out << '\n'; } } @@ -727,28 +745,28 @@ void t_cpp_generator::generate_consts(std::vector consts) { f_consts_impl << autogen_comment(); // Start ifndef - f_consts << "#ifndef " << program_name_ << "_CONSTANTS_H" << endl << "#define " << program_name_ - << "_CONSTANTS_H" << endl << endl << "#include \"" << get_include_prefix(*get_program()) - << program_name_ << "_types.h\"" << endl << endl << ns_open_ << endl << endl; + f_consts << "#ifndef " << program_name_ << "_CONSTANTS_H" << '\n' << "#define " << program_name_ + << "_CONSTANTS_H" << '\n' << '\n' << "#include \"" << get_include_prefix(*get_program()) + << program_name_ << "_types.h\"" << '\n' << '\n' << ns_open_ << '\n' << '\n'; f_consts_impl << "#include \"" << get_include_prefix(*get_program()) << program_name_ - << "_constants.h\"" << endl << endl << ns_open_ << endl << endl; + << "_constants.h\"" << '\n' << '\n' << ns_open_ << '\n' << '\n'; - f_consts << "class " << program_name_ << "Constants {" << endl << " public:" << endl << " " - << program_name_ << "Constants();" << endl << endl; + f_consts << "class " << program_name_ << "Constants {" << '\n' << " public:" << '\n' << " " + << program_name_ << "Constants();" << '\n' << '\n'; indent_up(); vector::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(); - f_consts << indent() << type_name(type) << " " << name << ";" << endl; + f_consts << indent() << type_name(type) << " " << name << ";" << '\n'; } indent_down(); - f_consts << "};" << endl; + f_consts << "};" << '\n'; f_consts_impl << "const " << program_name_ << "Constants g_" << program_name_ << "_constants;" - << endl << endl << program_name_ << "Constants::" << program_name_ - << "Constants() {" << endl; + << '\n' << '\n' << program_name_ << "Constants::" << program_name_ + << "Constants() {" << '\n'; indent_up(); for (c_iter = consts.begin(); c_iter != consts.end(); ++c_iter) { print_const_value(f_consts_impl, @@ -757,13 +775,13 @@ void t_cpp_generator::generate_consts(std::vector consts) { (*c_iter)->get_value()); } indent_down(); - indent(f_consts_impl) << "}" << endl; + indent(f_consts_impl) << "}" << '\n'; - f_consts << endl << "extern const " << program_name_ << "Constants g_" << program_name_ - << "_constants;" << endl << endl << ns_close_ << endl << endl << "#endif" << endl; + f_consts << '\n' << "extern const " << program_name_ << "Constants g_" << program_name_ + << "_constants;" << '\n' << '\n' << ns_close_ << '\n' << '\n' << "#endif" << '\n'; f_consts.close(); - f_consts_impl << endl << ns_close_ << endl << endl; + f_consts_impl << '\n' << ns_close_ << '\n' << '\n'; f_consts_impl.close(); } } @@ -779,12 +797,12 @@ void t_cpp_generator::print_const_value(ostream& out, t_const_value* value) { type = get_true_type(type); if (type->is_base_type()) { - string v2 = render_const_value(out, name, type, value); - indent(out) << name << " = " << v2 << ";" << endl << endl; + string v2 = render_const_value(&out, name, type, value); + indent(out) << name << " = " << v2 << ";" << '\n' << '\n'; } else if (type->is_enum()) { indent(out) << name << " = static_cast<" << type_name(type) << '>' - << '(' << value->get_integer() << ");" << endl << endl; + << '(' << value->get_integer() << ");" << '\n' << '\n'; } else if (type->is_struct() || type->is_xception()) { const vector& fields = ((t_struct*)type)->get_members(); vector::const_iterator f_iter; @@ -803,42 +821,42 @@ void t_cpp_generator::print_const_value(ostream& out, if (field_type == nullptr) { throw "type error: " + type->get_name() + " has no field " + v_iter->first->get_string(); } - string item_val = render_const_value(out, name, field_type, v_iter->second); - indent(out) << name << "." << v_iter->first->get_string() << " = " << item_val << ";" << endl; + string item_val = render_const_value(&out, name, field_type, v_iter->second); + indent(out) << name << "." << v_iter->first->get_string() << " = " << item_val << ";" << '\n'; if (is_nonrequired_field) { - indent(out) << name << ".__isset." << v_iter->first->get_string() << " = true;" << endl; + indent(out) << name << ".__isset." << v_iter->first->get_string() << " = true;" << '\n'; } } - out << endl; + out << '\n'; } else if (type->is_map()) { t_type* ktype = ((t_map*)type)->get_key_type(); t_type* vtype = ((t_map*)type)->get_val_type(); const map& val = value->get_map(); map::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 item_val = render_const_value(out, name, vtype, v_iter->second); - indent(out) << name << ".insert(std::make_pair(" << key << ", " << item_val << "));" << endl; + string key = render_const_value(&out, name, ktype, v_iter->first); + string item_val = render_const_value(&out, name, vtype, v_iter->second); + indent(out) << name << ".insert(std::make_pair(" << key << ", " << item_val << "));" << '\n'; } - out << endl; + out << '\n'; } else if (type->is_list()) { t_type* etype = ((t_list*)type)->get_elem_type(); const vector& val = value->get_list(); vector::const_iterator v_iter; for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { - string item_val = render_const_value(out, name, etype, *v_iter); - indent(out) << name << ".push_back(" << item_val << ");" << endl; + string item_val = render_const_value(&out, name, etype, *v_iter); + indent(out) << name << ".push_back(" << item_val << ");" << '\n'; } - out << endl; + out << '\n'; } else if (type->is_set()) { t_type* etype = ((t_set*)type)->get_elem_type(); const vector& val = value->get_list(); vector::const_iterator v_iter; for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { - string item_val = render_const_value(out, name, etype, *v_iter); - indent(out) << name << ".insert(" << item_val << ");" << endl; + string item_val = render_const_value(&out, name, etype, *v_iter); + indent(out) << name << ".insert(" << item_val << ");" << '\n'; } - out << endl; + out << '\n'; } else { throw "INVALID TYPE IN print_const_value: " + type->get_name(); } @@ -847,7 +865,7 @@ void t_cpp_generator::print_const_value(ostream& out, /** * */ -string t_cpp_generator::render_const_value(ostream& out, +string t_cpp_generator::render_const_value(ostream* out, string name, t_type* type, t_const_value* value) { @@ -884,10 +902,10 @@ string t_cpp_generator::render_const_value(ostream& out, } else if (type->is_enum()) { render << "static_cast<" << type_name(type) << '>' << '(' << value->get_integer() << ')'; - } else { + } else if (out) { string t = tmp("tmp"); - indent(out) << type_name(type) << " " << t << ";" << endl; - print_const_value(out, t, type, value); + indent(*out) << type_name(type) << " " << t << ";" << '\n'; + print_const_value(*out, t, type, value); render << t; } @@ -896,7 +914,7 @@ string t_cpp_generator::render_const_value(ostream& out, void t_cpp_generator::generate_forward_declaration(t_struct* tstruct) { // Forward declare struct def - f_types_ << indent() << "class " << tstruct->get_name() << ";" << endl << endl; + f_types_ << indent() << "class " << tstruct->get_name() << ";" << '\n' << '\n'; } /** @@ -908,19 +926,24 @@ void t_cpp_generator::generate_forward_declaration(t_struct* tstruct) { */ void t_cpp_generator::generate_cpp_struct(t_struct* tstruct, bool is_exception) { generate_struct_declaration(f_types_, tstruct, is_exception, false, true, true, true, true); - generate_struct_definition(f_types_impl_, f_types_impl_, tstruct, true, true); + generate_struct_definition(f_types_impl_, f_types_impl_, tstruct, true, true, false); std::ostream& out = (gen_templates_ ? f_types_tcc_ : f_types_impl_); generate_struct_reader(out, tstruct); generate_struct_writer(out, tstruct); generate_struct_swap(f_types_impl_, tstruct); - generate_copy_constructor(f_types_impl_, tstruct, is_exception); - if (gen_moveable_) { - generate_move_constructor(f_types_impl_, tstruct, is_exception); + if (!gen_no_default_operators_) { + generate_equality_operator(f_types_impl_, tstruct); } - generate_assignment_operator(f_types_impl_, tstruct); - if (gen_moveable_) { - generate_move_assignment_operator(f_types_impl_, tstruct); + if (!gen_no_constructors_) { + generate_copy_constructor(f_types_impl_, tstruct, is_exception); + if (gen_moveable_) { + generate_move_constructor(f_types_impl_, tstruct, is_exception); + } + generate_assignment_operator(f_types_impl_, tstruct); + if (gen_moveable_) { + generate_move_assignment_operator(f_types_impl_, tstruct); + } } if (!has_custom_ostream(tstruct)) { @@ -934,6 +957,130 @@ void t_cpp_generator::generate_cpp_struct(t_struct* tstruct, bool is_exception) has_members_ = true; } +void t_cpp_generator::generate_equality_operator(std::ostream& out, t_struct* tstruct) { + // Get members + vector::const_iterator m_iter; + const vector& members = tstruct->get_members(); + + out << indent() << "bool " << tstruct->get_name() + << "::operator==(const " << tstruct->get_name() << " & " + << (members.size() > 0 ? "rhs" : "/* rhs */") << ") const" << '\n'; + scope_up(out); + for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { + // Most existing Thrift code does not use isset or optional/required, + // so we treat "default" fields as required. + if ((*m_iter)->get_req() != t_field::T_OPTIONAL) { + out << indent() << "if (!(" << (*m_iter)->get_name() << " == rhs." + << (*m_iter)->get_name() << "))" << '\n' << indent() << " return false;" << '\n'; + } else { + out << indent() << "if (__isset." << (*m_iter)->get_name() << " != rhs.__isset." + << (*m_iter)->get_name() << ")" << '\n' << indent() << " return false;" << '\n' + << indent() << "else if (__isset." << (*m_iter)->get_name() << " && !(" + << (*m_iter)->get_name() << " == rhs." << (*m_iter)->get_name() << "))" << '\n' + << indent() << " return false;" << '\n'; + } + } + indent(out) << "return true;" << '\n'; + scope_down(out); + out << '\n'; +} + +bool t_cpp_generator::has_field_with_default_value(t_struct* tstruct) +{ + vector::const_iterator m_iter; + const vector& members = tstruct->get_members(); + + for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { + t_type* t = get_true_type((*m_iter)->get_type()); + if (is_reference(*m_iter) || t->is_string() || t->is_uuid()) { + t_const_value* cv = (*m_iter)->get_value(); + if (cv != nullptr) { + return true; + } + } + } + + return false; +} + +void t_cpp_generator::generate_default_constructor(ostream& out, + t_struct* tstruct, + bool is_exception) { + // Get members + vector::const_iterator m_iter; + const vector& members = tstruct->get_members(); + + bool has_default_value = has_field_with_default_value(tstruct); + + std::string clsname_ctor = tstruct->get_name() + "::" + tstruct->get_name() + "()"; + indent(out) << clsname_ctor << (has_default_value ? "" : " noexcept"); + + // + // Start generating initializer list + // + + bool init_ctor = false; + std::string args_indent(" "); + + // Default-initialize TException, if it is our base type + if (is_exception) + { + out << '\n'; + indent(out) << " : "; + out << "TException()"; + init_ctor = true; + } + + // Default-initialize all members that should be initialized in + // the initializer block + for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { + t_type* t = get_true_type((*m_iter)->get_type()); + if (t->is_base_type() || t->is_enum() || is_reference(*m_iter)) { + string dval; + t_const_value* cv = (*m_iter)->get_value(); + if (cv != nullptr) { + dval += render_const_value(&out, (*m_iter)->get_name(), t, cv); + } else if (t->is_enum()) { + dval += "static_cast<" + type_name(t) + ">(0)"; + } else { + dval += (t->is_string() || is_reference(*m_iter) || t->is_uuid()) ? "" : "0"; + } + if (!init_ctor) { + init_ctor = true; + if(has_default_value) { + out << " : "; + } else { + out << '\n' << args_indent << ": "; + args_indent.append(" "); + } + } else { + out << ",\n" << args_indent; + } + + out << (*m_iter)->get_name() << "(" << dval << ")"; + } + } + + // + // Start generating body + // + + out << " {" << '\n'; + indent_up(); + // TODO(dreiss): When everything else in Thrift is perfect, + // do more of these in the initializer list. + for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { + t_type* t = get_true_type((*m_iter)->get_type()); + if (!t->is_base_type() && !t->is_enum() && !is_reference(*m_iter)) { + t_const_value* cv = (*m_iter)->get_value(); + if (cv != nullptr) { + print_const_value(out, (*m_iter)->get_name(), t, cv); + } + } + } + scope_down(out); +} + void t_cpp_generator::generate_copy_constructor(ostream& out, t_struct* tstruct, bool is_exception) { @@ -975,14 +1122,14 @@ void t_cpp_generator::generate_constructor_helper(ostream& out, out << "noexcept "; if (is_exception) out << ": TException() "; - out << "{" << endl; + out << "{" << '\n'; indent_up(); const vector& members = tstruct->get_members(); // eliminate compiler unused warning if (members.empty()) - indent(out) << "(void) " << tmp_name << ";" << endl; + indent(out) << "(void) " << tmp_name << ";" << '\n'; vector::const_iterator f_iter; bool has_nonrequired_fields = false; @@ -991,17 +1138,17 @@ void t_cpp_generator::generate_constructor_helper(ostream& out, has_nonrequired_fields = true; indent(out) << (*f_iter)->get_name() << " = " << maybeMove( - tmp_name + "." + (*f_iter)->get_name(), + tmp_name + "." + (*f_iter)->get_name(), is_move && is_complex_type((*f_iter)->get_type())) - << ";" << endl; + << ";" << '\n'; } if (has_nonrequired_fields) { - indent(out) << "__isset = " << maybeMove(tmp_name + ".__isset", false) << ";" << endl; + indent(out) << "__isset = " << maybeMove(tmp_name + ".__isset", false) << ";" << '\n'; } indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } void t_cpp_generator::generate_assignment_operator(ostream& out, t_struct* tstruct) { @@ -1025,14 +1172,14 @@ void t_cpp_generator::generate_assignment_helper(ostream& out, t_struct* tstruct out << tmp_name << ") "; if(is_move || is_struct_storage_not_throwing(tstruct)) out << "noexcept "; - out << "{" << endl; + out << "{" << '\n'; indent_up(); const vector& members = tstruct->get_members(); // eliminate compiler unused warning if (members.empty()) - indent(out) << "(void) " << tmp_name << ";" << endl; + indent(out) << "(void) " << tmp_name << ";" << '\n'; vector::const_iterator f_iter; bool has_nonrequired_fields = false; @@ -1041,17 +1188,17 @@ void t_cpp_generator::generate_assignment_helper(ostream& out, t_struct* tstruct has_nonrequired_fields = true; indent(out) << (*f_iter)->get_name() << " = " << maybeMove( - tmp_name + "." + (*f_iter)->get_name(), + tmp_name + "." + (*f_iter)->get_name(), is_move && is_complex_type((*f_iter)->get_type())) - << ";" << endl; + << ";" << '\n'; } if (has_nonrequired_fields) { - indent(out) << "__isset = " << maybeMove(tmp_name + ".__isset", false) << ";" << endl; + indent(out) << "__isset = " << maybeMove(tmp_name + ".__isset", false) << ";" << '\n'; } - indent(out) << "return *this;" << endl; + indent(out) << "return *this;" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } /** @@ -1094,7 +1241,7 @@ void t_cpp_generator::generate_struct_declaration(ostream& out, if (has_nonrequired_fields && (!pointers || read)) { - out << indent() << "typedef struct _" << tstruct->get_name() << "__isset {" << endl; + out << indent() << "typedef struct _" << tstruct->get_name() << "__isset {" << '\n'; indent_up(); indent(out) << "_" << tstruct->get_name() << "__isset() "; @@ -1111,127 +1258,74 @@ void t_cpp_generator::generate_struct_declaration(ostream& out, out << ", " << (*m_iter)->get_name() << "(" << isSet << ")"; } } - out << " {}" << endl; + out << " {}" << '\n'; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { if ((*m_iter)->get_req() != t_field::T_REQUIRED) { - indent(out) << "bool " << (*m_iter)->get_name() << " :1;" << endl; + indent(out) << "bool " << (*m_iter)->get_name() << " :1;" << '\n'; } } indent_down(); - indent(out) << "} _" << tstruct->get_name() << "__isset;" << endl; + indent(out) << "} _" << tstruct->get_name() << "__isset;" << '\n'; } - out << endl; + out << '\n'; generate_java_doc(out, tstruct); // Open struct def - out << indent() << "class " << tstruct->get_name() << extends << " {" << endl << indent() - << " public:" << endl << endl; + out << indent() << "class " << tstruct->get_name() << extends << " {" << '\n' << indent() + << " public:" << '\n' << '\n'; indent_up(); - if (!pointers) { + if (!gen_no_constructors_ && !pointers) { bool ok_noexcept = is_struct_storage_not_throwing(tstruct); // Copy constructor indent(out) << tstruct->get_name() << "(const " << tstruct->get_name() << "&)" - << (ok_noexcept? " noexcept" : "") << ';' << endl; + << (ok_noexcept? " noexcept" : "") << ';' << '\n'; // Move constructor if (gen_moveable_) { - indent(out) << tstruct->get_name() << "(" << tstruct->get_name() << "&&) noexcept;" - << endl; + indent(out) << tstruct->get_name() << "(" << tstruct->get_name() << "&&) noexcept;" + << '\n'; } // Assignment Operator indent(out) << tstruct->get_name() << "& operator=(const " << tstruct->get_name() << "&)" - << (ok_noexcept? " noexcept" : "") << ';' << endl; + << (ok_noexcept? " noexcept" : "") << ';' << '\n'; // Move assignment operator if (gen_moveable_) { - indent(out) << tstruct->get_name() << "& operator=(" << tstruct->get_name() << "&&) noexcept;" - << endl; + indent(out) << tstruct->get_name() << "& operator=(" << tstruct->get_name() << "&&) noexcept;" + << '\n'; } - bool has_default_value = false; - for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { - t_type* t = get_true_type((*m_iter)->get_type()); - if (is_reference(*m_iter) || t->is_string()) { - t_const_value* cv = (*m_iter)->get_value(); - if (cv != nullptr) { - has_default_value = true; - break; - } - } - } + bool has_default_value = has_field_with_default_value(tstruct); // Default constructor std::string clsname_ctor = tstruct->get_name() + "()"; - indent(out) << clsname_ctor << (has_default_value ? "" : " noexcept"); - - bool init_ctor = false; - std::string args_indent( - indent().size() + clsname_ctor.size() + (has_default_value ? 3 : -1), ' '); - - for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { - t_type* t = get_true_type((*m_iter)->get_type()); - if (t->is_base_type() || t->is_enum() || is_reference(*m_iter)) { - string dval; - t_const_value* cv = (*m_iter)->get_value(); - if (cv != nullptr) { - dval += render_const_value(out, (*m_iter)->get_name(), t, cv); - } else if (t->is_enum()) { - dval += "static_cast<" + type_name(t) + ">(0)"; - } else { - dval += (t->is_string() || is_reference(*m_iter)) ? "" : "0"; - } - if (!init_ctor) { - init_ctor = true; - if(has_default_value) { - out << " : "; - } else { - out << '\n' << args_indent << ": "; - args_indent.append(" "); - } - } else { - out << ",\n" << args_indent; - } - out << (*m_iter)->get_name() << "(" << dval << ")"; - } - } - out << " {" << endl; - indent_up(); - // TODO(dreiss): When everything else in Thrift is perfect, - // do more of these in the initializer list. - for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { - t_type* t = get_true_type((*m_iter)->get_type()); - if (!t->is_base_type() && !t->is_enum() && !is_reference(*m_iter)) { - t_const_value* cv = (*m_iter)->get_value(); - if (cv != nullptr) { - print_const_value(out, (*m_iter)->get_name(), t, cv); - } - } - } - scope_down(out); + indent(out) << clsname_ctor << (has_default_value ? "" : " noexcept") << ";" << '\n'; } - if (tstruct->annotations_.find("final") == tstruct->annotations_.end()) { - out << endl << indent() << "virtual ~" << tstruct->get_name() << "() noexcept;" << endl; + if (!gen_no_constructors_ && tstruct->annotations_.find("final") == tstruct->annotations_.end()) { + out << '\n' << indent(); + if (!gen_templates_) out << "virtual "; + out << "~" << tstruct->get_name() << "() noexcept;\n"; } // Declare all fields for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { generate_java_doc(out, *m_iter); indent(out) << declare_field(*m_iter, - false, + !pointers && gen_no_constructors_, (pointers && !(*m_iter)->get_type()->is_xception()), - !read) << endl; + !read) << '\n'; } // Add the __isset data member if we need it, using the definition from above if (has_nonrequired_fields && (!pointers || read)) { - out << endl << indent() << "_" << tstruct->get_name() << "__isset __isset;" << endl; + out << '\n' << indent() << "_" << tstruct->get_name() << "__isset __isset;" << '\n'; } // Create a setter function for each field @@ -1240,104 +1334,88 @@ void t_cpp_generator::generate_struct_declaration(ostream& out, continue; } if (is_reference((*m_iter))) { - out << endl << indent() << "void __set_" << (*m_iter)->get_name() << "(::std::shared_ptr<" + out << '\n' << indent() << "void __set_" << (*m_iter)->get_name() << "(::std::shared_ptr<" << type_name((*m_iter)->get_type(), false, false) << ">"; - out << " val);" << endl; + out << " val);" << '\n'; } else { - out << endl << indent() << "void __set_" << (*m_iter)->get_name() << "(" + out << '\n' << indent() << "void __set_" << (*m_iter)->get_name() << "(" << type_name((*m_iter)->get_type(), false, true); - out << " val);" << endl; + out << " val);" << '\n'; } } - out << endl; + out << '\n'; if (!pointers) { // Should we generate default operators? if (!gen_no_default_operators_) { - // Generate an equality testing operator. Make it inline since the compiler - // will do a better job than we would when deciding whether to inline it. + // Generate an equality testing operator. out << indent() << "bool operator == (const " << tstruct->get_name() << " & " - << (members.size() > 0 ? "rhs" : "/* rhs */") << ") const" << endl; - scope_up(out); - for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { - // Most existing Thrift code does not use isset or optional/required, - // so we treat "default" fields as required. - if ((*m_iter)->get_req() != t_field::T_OPTIONAL) { - out << indent() << "if (!(" << (*m_iter)->get_name() << " == rhs." - << (*m_iter)->get_name() << "))" << endl << indent() << " return false;" << endl; - } else { - out << indent() << "if (__isset." << (*m_iter)->get_name() << " != rhs.__isset." - << (*m_iter)->get_name() << ")" << endl << indent() << " return false;" << endl - << indent() << "else if (__isset." << (*m_iter)->get_name() << " && !(" - << (*m_iter)->get_name() << " == rhs." << (*m_iter)->get_name() << "))" << endl - << indent() << " return false;" << endl; - } - } - indent(out) << "return true;" << endl; - scope_down(out); + << (members.size() > 0 ? "rhs" : "/* rhs */") << ") const;" << '\n'; + out << indent() << "bool operator != (const " << tstruct->get_name() << " &rhs) const {" - << endl << indent() << " return !(*this == rhs);" << endl << indent() << "}" << endl - << endl; + << '\n' << indent() << " return !(*this == rhs);" << '\n' << indent() << "}" << '\n' + << '\n'; // Generate the declaration of a less-than operator. This must be // implemented by the application developer if they wish to use it. (They // will get a link error if they try to use it without an implementation.) - out << indent() << "bool operator < (const " << tstruct->get_name() << " & ) const;" << endl - << endl; + out << indent() << "bool operator < (const " << tstruct->get_name() << " & ) const;" << '\n' + << '\n'; } } if (read) { if (gen_templates_) { - out << indent() << "template " << endl << indent() - << "uint32_t read(Protocol_* iprot);" << endl; + out << indent() << "template " << '\n' << indent() + << "uint32_t read(Protocol_* iprot);" << '\n'; } else { out << indent() << "uint32_t read(" << "::apache::thrift::protocol::TProtocol* iprot)"; if(!is_exception && !extends.empty()) out << " override"; - out << ';' << endl; + out << ';' << '\n'; } } if (write) { if (gen_templates_) { - out << indent() << "template " << endl << indent() - << "uint32_t write(Protocol_* oprot) const;" << endl; + out << indent() << "template " << '\n' << indent() + << "uint32_t write(Protocol_* oprot) const;" << '\n'; } else { out << indent() << "uint32_t write(" << "::apache::thrift::protocol::TProtocol* oprot) const"; if(!is_exception && !extends.empty()) out << " override"; - out << ';' << endl; + out << ';' << '\n'; } } - out << endl; + out << '\n'; if (is_user_struct && !has_custom_ostream(tstruct)) { - out << indent() << "virtual "; + out << indent(); + if (!gen_templates_) out << "virtual "; generate_struct_print_method_decl(out, nullptr); - out << ";" << endl; + out << ";" << '\n'; } // std::exception::what() if (is_exception) { - out << indent() << "mutable std::string thriftTExceptionMessageHolder_;" << endl; + out << indent() << "mutable std::string thriftTExceptionMessageHolder_;" << '\n'; out << indent(); generate_exception_what_method_decl(out, tstruct, false); - out << ";" << endl; + out << ";" << '\n'; } indent_down(); - indent(out) << "};" << endl << endl; + indent(out) << "};" << '\n' << '\n'; if (swap) { // Generate a namespace-scope swap() function if (tstruct->get_name() == "a" || tstruct->get_name() == "b") { out << indent() << "void swap(" << tstruct->get_name() << " &a1, " << tstruct->get_name() - << " &a2);" << endl << endl; + << " &a2);" << '\n' << '\n'; } else { out << indent() << "void swap(" << tstruct->get_name() << " &a, " << tstruct->get_name() - << " &b);" << endl << endl; + << " &b);" << '\n' << '\n'; } } @@ -1350,51 +1428,60 @@ void t_cpp_generator::generate_struct_definition(ostream& out, ostream& force_cpp_out, t_struct* tstruct, bool setters, - bool is_user_struct) { + bool is_user_struct, + bool pointers) { // Get members vector::const_iterator m_iter; const vector& members = tstruct->get_members(); // Destructor - if (tstruct->annotations_.find("final") == tstruct->annotations_.end()) { - force_cpp_out << endl << indent() << tstruct->get_name() << "::~" << tstruct->get_name() - << "() noexcept {" << endl; + if (!gen_no_constructors_ && tstruct->annotations_.find("final") == tstruct->annotations_.end()) { + force_cpp_out << '\n' << indent() << tstruct->get_name() << "::~" << tstruct->get_name() + << "() noexcept {" << '\n'; indent_up(); indent_down(); - force_cpp_out << indent() << "}" << endl << endl; + force_cpp_out << indent() << "}" << '\n' << '\n'; + } + + if (!gen_no_constructors_ && !pointers) + { + // 'force_cpp_out' always goes into the .cpp file, and never into a .tcc + // file in case templates are involved. Since the constructor is not templated, + // putting it into the (later included) .tcc file would cause ODR violations. + generate_default_constructor(force_cpp_out, tstruct, false); } // Create a setter function for each field if (setters) { for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { if (is_reference((*m_iter))) { - out << endl << indent() << "void " << tstruct->get_name() << "::__set_" + out << '\n' << indent() << "void " << tstruct->get_name() << "::__set_" << (*m_iter)->get_name() << "(::std::shared_ptr<" << type_name((*m_iter)->get_type(), false, false) << ">"; - out << " val) {" << endl; + out << " val) {" << '\n'; } else { - out << endl << indent() << "void " << tstruct->get_name() << "::__set_" + out << '\n' << indent() << "void " << tstruct->get_name() << "::__set_" << (*m_iter)->get_name() << "(" << type_name((*m_iter)->get_type(), false, true); - out << " val) {" << endl; + out << " val) {" << '\n'; } indent_up(); - out << indent() << "this->" << (*m_iter)->get_name() << " = val;" << endl; + out << indent() << "this->" << (*m_iter)->get_name() << " = val;" << '\n'; indent_down(); // assume all fields are required except optional fields. // for optional fields change __isset.name to true bool is_optional = (*m_iter)->get_req() == t_field::T_OPTIONAL; if (is_optional) { - out << indent() << indent() << "__isset." << (*m_iter)->get_name() << " = true;" << endl; + out << indent() << indent() << "__isset." << (*m_iter)->get_name() << " = true;" << '\n'; } - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } } if (is_user_struct) { generate_struct_ostream_operator(out, tstruct); } - out << endl; + out << '\n'; } /** @@ -1405,11 +1492,11 @@ void t_cpp_generator::generate_struct_definition(ostream& out, */ void t_cpp_generator::generate_struct_reader(ostream& out, t_struct* tstruct, bool pointers) { if (gen_templates_) { - out << indent() << "template " << endl << indent() << "uint32_t " - << tstruct->get_name() << "::read(Protocol_* iprot) {" << endl; + out << indent() << "template " << '\n' << indent() << "uint32_t " + << tstruct->get_name() << "::read(Protocol_* iprot) {" << '\n'; } else { indent(out) << "uint32_t " << tstruct->get_name() - << "::read(::apache::thrift::protocol::TProtocol* iprot) {" << endl; + << "::read(::apache::thrift::protocol::TProtocol* iprot) {" << '\n'; } indent_up(); @@ -1417,49 +1504,49 @@ void t_cpp_generator::generate_struct_reader(ostream& out, t_struct* tstruct, bo vector::const_iterator f_iter; // Declare stack tmp variables - out << endl - << indent() << "::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);" << endl - << indent() << "uint32_t xfer = 0;" << endl - << indent() << "std::string fname;" << endl - << indent() << "::apache::thrift::protocol::TType ftype;" << endl - << indent() << "int16_t fid;" << endl - << endl - << indent() << "xfer += iprot->readStructBegin(fname);" << endl - << endl - << indent() << "using ::apache::thrift::protocol::TProtocolException;" << endl - << endl; + out << '\n' + << indent() << "::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);" << '\n' + << indent() << "uint32_t xfer = 0;" << '\n' + << indent() << "std::string fname;" << '\n' + << indent() << "::apache::thrift::protocol::TType ftype;" << '\n' + << indent() << "int16_t fid;" << '\n' + << '\n' + << indent() << "xfer += iprot->readStructBegin(fname);" << '\n' + << '\n' + << indent() << "using ::apache::thrift::protocol::TProtocolException;" << '\n' + << '\n'; // 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 ((*f_iter)->get_req() == t_field::T_REQUIRED) - indent(out) << "bool isset_" << (*f_iter)->get_name() << " = false;" << endl; + indent(out) << "bool isset_" << (*f_iter)->get_name() << " = false;" << '\n'; } - out << endl; + out << '\n'; // Loop over reading in fields - indent(out) << "while (true)" << endl; + indent(out) << "while (true)" << '\n'; scope_up(out); // Read beginning field marker - indent(out) << "xfer += iprot->readFieldBegin(fname, ftype, fid);" << endl; + indent(out) << "xfer += iprot->readFieldBegin(fname, ftype, fid);" << '\n'; // Check for field STOP marker - out << indent() << "if (ftype == ::apache::thrift::protocol::T_STOP) {" << endl << indent() - << " break;" << endl << indent() << "}" << endl; + out << indent() << "if (ftype == ::apache::thrift::protocol::T_STOP) {" << '\n' << indent() + << " break;" << '\n' << indent() << "}" << '\n'; if (fields.empty()) { - out << indent() << "xfer += iprot->skip(ftype);" << endl; + out << indent() << "xfer += iprot->skip(ftype);" << '\n'; } else { // Switch statement on the field we are reading - indent(out) << "switch (fid)" << endl; + indent(out) << "switch (fid)" << '\n'; 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(out) << "case " << (*f_iter)->get_key() << ":" << '\n'; indent_up(); - indent(out) << "if (ftype == " << type_to_enum((*f_iter)->get_type()) << ") {" << endl; + indent(out) << "if (ftype == " << type_to_enum((*f_iter)->get_type()) << ") {" << '\n'; indent_up(); const char* isset_prefix = ((*f_iter)->get_req() != t_field::T_REQUIRED) ? "this->__isset." @@ -1471,8 +1558,8 @@ void t_cpp_generator::generate_struct_reader(ostream& out, t_struct* tstruct, bo // TODO(dreiss): Generate this code and "if" it out to make it easier // for people recompiling thrift to include it. out << - indent() << "if (" << isset_prefix << (*f_iter)->get_name() << ")" << endl << - indent() << " throw TProtocolException(TProtocolException::INVALID_DATA);" << endl; + indent() << "if (" << isset_prefix << (*f_iter)->get_name() << ")" << '\n' << + indent() << " throw TProtocolException(TProtocolException::INVALID_DATA);" << '\n'; #endif if (pointers && !(*f_iter)->get_type()->is_xception()) { @@ -1480,44 +1567,44 @@ void t_cpp_generator::generate_struct_reader(ostream& out, t_struct* tstruct, bo } else { generate_deserialize_field(out, *f_iter, "this->"); } - out << indent() << isset_prefix << (*f_iter)->get_name() << " = true;" << endl; + out << indent() << isset_prefix << (*f_iter)->get_name() << " = true;" << '\n'; indent_down(); - out << indent() << "} else {" << endl << indent() << " xfer += iprot->skip(ftype);" << endl + out << indent() << "} else {" << '\n' << indent() << " xfer += iprot->skip(ftype);" << '\n' << // TODO(dreiss): Make this an option when thrift structs // have a common base class. - // indent() << " throw TProtocolException(TProtocolException::INVALID_DATA);" << endl << - indent() << "}" << endl << indent() << "break;" << endl; + // indent() << " throw TProtocolException(TProtocolException::INVALID_DATA);" << '\n' << + indent() << "}" << '\n' << indent() << "break;" << '\n'; indent_down(); } // In the default case we skip the field - out << indent() << "default:" << endl << indent() << " xfer += iprot->skip(ftype);" << endl - << indent() << " break;" << endl; + out << indent() << "default:" << '\n' << indent() << " xfer += iprot->skip(ftype);" << '\n' + << indent() << " break;" << '\n'; scope_down(out); } //!fields.empty() // Read field end marker - indent(out) << "xfer += iprot->readFieldEnd();" << endl; + indent(out) << "xfer += iprot->readFieldEnd();" << '\n'; scope_down(out); - out << endl << indent() << "xfer += iprot->readStructEnd();" << endl; + out << '\n' << indent() << "xfer += iprot->readStructEnd();" << '\n'; // Throw if any required fields are missing. // We do this after reading the struct end so that // there might possibly be a chance of continuing. - out << endl; + out << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if ((*f_iter)->get_req() == t_field::T_REQUIRED) - out << indent() << "if (!isset_" << (*f_iter)->get_name() << ')' << endl << indent() - << " throw TProtocolException(TProtocolException::INVALID_DATA);" << endl; + out << indent() << "if (!isset_" << (*f_iter)->get_name() << ')' << '\n' << indent() + << " throw TProtocolException(TProtocolException::INVALID_DATA);" << '\n'; } - indent(out) << "return xfer;" << endl; + indent(out) << "return xfer;" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } /** @@ -1532,33 +1619,33 @@ void t_cpp_generator::generate_struct_writer(ostream& out, t_struct* tstruct, bo vector::const_iterator f_iter; if (gen_templates_) { - out << indent() << "template " << endl << indent() << "uint32_t " - << tstruct->get_name() << "::write(Protocol_* oprot) const {" << endl; + out << indent() << "template " << '\n' << indent() << "uint32_t " + << tstruct->get_name() << "::write(Protocol_* oprot) const {" << '\n'; } else { indent(out) << "uint32_t " << tstruct->get_name() - << "::write(::apache::thrift::protocol::TProtocol* oprot) const {" << endl; + << "::write(::apache::thrift::protocol::TProtocol* oprot) const {" << '\n'; } indent_up(); - out << indent() << "uint32_t xfer = 0;" << endl; + out << indent() << "uint32_t xfer = 0;" << '\n'; - indent(out) << "::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);" << endl; - indent(out) << "xfer += oprot->writeStructBegin(\"" << name << "\");" << endl; + indent(out) << "::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);" << '\n'; + indent(out) << "xfer += oprot->writeStructBegin(\"" << name << "\");" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { bool check_if_set = (*f_iter)->get_req() == t_field::T_OPTIONAL || (*f_iter)->get_type()->is_xception(); if (check_if_set) { - out << endl << indent() << "if (this->__isset." << (*f_iter)->get_name() << ") {" << endl; + out << '\n' << indent() << "if (this->__isset." << (*f_iter)->get_name() << ") {" << '\n'; indent_up(); } else { - out << endl; + out << '\n'; } // Write field header out << indent() << "xfer += oprot->writeFieldBegin(" << "\"" << (*f_iter)->get_name() << "\", " << type_to_enum((*f_iter)->get_type()) << ", " - << (*f_iter)->get_key() << ");" << endl; + << (*f_iter)->get_key() << ");" << '\n'; // Write field contents if (pointers && !(*f_iter)->get_type()->is_xception()) { generate_serialize_field(out, *f_iter, "(*(this->", "))"); @@ -1566,22 +1653,22 @@ void t_cpp_generator::generate_struct_writer(ostream& out, t_struct* tstruct, bo generate_serialize_field(out, *f_iter, "this->"); } // Write field closer - indent(out) << "xfer += oprot->writeFieldEnd();" << endl; + indent(out) << "xfer += oprot->writeFieldEnd();" << '\n'; if (check_if_set) { indent_down(); indent(out) << '}'; } } - out << endl; + out << '\n'; // Write the struct map - out << indent() << "xfer += oprot->writeFieldStop();" << endl << indent() - << "xfer += oprot->writeStructEnd();" << endl << indent() - << "return xfer;" << endl; + out << indent() << "xfer += oprot->writeFieldStop();" << '\n' << indent() + << "xfer += oprot->writeStructEnd();" << '\n' << indent() + << "return xfer;" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } /** @@ -1600,35 +1687,35 @@ void t_cpp_generator::generate_struct_result_writer(ostream& out, vector::const_iterator f_iter; if (gen_templates_) { - out << indent() << "template " << endl << indent() << "uint32_t " - << tstruct->get_name() << "::write(Protocol_* oprot) const {" << endl; + out << indent() << "template " << '\n' << indent() << "uint32_t " + << tstruct->get_name() << "::write(Protocol_* oprot) const {" << '\n'; } else { indent(out) << "uint32_t " << tstruct->get_name() - << "::write(::apache::thrift::protocol::TProtocol* oprot) const {" << endl; + << "::write(::apache::thrift::protocol::TProtocol* oprot) const {" << '\n'; } indent_up(); - out << endl << indent() << "uint32_t xfer = 0;" << endl << endl; + out << '\n' << indent() << "uint32_t xfer = 0;" << '\n' << '\n'; - indent(out) << "xfer += oprot->writeStructBegin(\"" << name << "\");" << endl; + indent(out) << "xfer += oprot->writeStructBegin(\"" << name << "\");" << '\n'; bool first = true; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if (first) { first = false; - out << endl << indent() << "if "; + out << '\n' << indent() << "if "; } else { out << " else if "; } - out << "(this->__isset." << (*f_iter)->get_name() << ") {" << endl; + out << "(this->__isset." << (*f_iter)->get_name() << ") {" << '\n'; indent_up(); // Write field header out << indent() << "xfer += oprot->writeFieldBegin(" << "\"" << (*f_iter)->get_name() << "\", " << type_to_enum((*f_iter)->get_type()) << ", " - << (*f_iter)->get_key() << ");" << endl; + << (*f_iter)->get_key() << ");" << '\n'; // Write field contents if (pointers) { generate_serialize_field(out, *f_iter, "(*(this->", "))"); @@ -1636,18 +1723,18 @@ void t_cpp_generator::generate_struct_result_writer(ostream& out, generate_serialize_field(out, *f_iter, "this->"); } // Write field closer - indent(out) << "xfer += oprot->writeFieldEnd();" << endl; + indent(out) << "xfer += oprot->writeFieldEnd();" << '\n'; indent_down(); indent(out) << "}"; } // Write the struct map - out << endl << indent() << "xfer += oprot->writeFieldStop();" << endl << indent() - << "xfer += oprot->writeStructEnd();" << endl << indent() << "return xfer;" << endl; + out << '\n' << indent() << "xfer += oprot->writeFieldStop();" << '\n' << indent() + << "xfer += oprot->writeStructEnd();" << '\n' << indent() << "return xfer;" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } /** @@ -1659,10 +1746,10 @@ void t_cpp_generator::generate_struct_result_writer(ostream& out, void t_cpp_generator::generate_struct_swap(ostream& out, t_struct* tstruct) { if (tstruct->get_name() == "a" || tstruct->get_name() == "b") { out << indent() << "void swap(" << tstruct->get_name() << " &a1, " << tstruct->get_name() - << " &a2) {" << endl; + << " &a2) {" << '\n'; } else { out << indent() << "void swap(" << tstruct->get_name() << " &a, " << tstruct->get_name() - << " &b) {" << endl; + << " &b) {" << '\n'; } indent_up(); @@ -1670,7 +1757,7 @@ void t_cpp_generator::generate_struct_swap(ostream& out, t_struct* tstruct) { // Let argument-dependent name lookup find the correct swap() function to // use based on the argument types. If none is found in the arguments' // namespaces, fall back to ::std::swap(). - out << indent() << "using ::std::swap;" << endl; + out << indent() << "using ::std::swap;" << '\n'; bool has_nonrequired_fields = false; const vector& fields = tstruct->get_members(); @@ -1681,41 +1768,41 @@ void t_cpp_generator::generate_struct_swap(ostream& out, t_struct* tstruct) { if (tstruct->get_name() == "a" || tstruct->get_name() == "b") { out << indent() << "swap(a1." << tfield->get_name() << ", a2." << tfield->get_name() << ");" - << endl; + << '\n'; } else { out << indent() << "swap(a." << tfield->get_name() << ", b." << tfield->get_name() << ");" - << endl; + << '\n'; } } if (has_nonrequired_fields) { if (tstruct->get_name() == "a" || tstruct->get_name() == "b") { - out << indent() << "swap(a1.__isset, a2.__isset);" << endl; + out << indent() << "swap(a1.__isset, a2.__isset);" << '\n'; } else { - out << indent() << "swap(a.__isset, b.__isset);" << endl; + out << indent() << "swap(a.__isset, b.__isset);" << '\n'; } } // handle empty structs if (fields.size() == 0) { if (tstruct->get_name() == "a" || tstruct->get_name() == "b") { - out << indent() << "(void) a1;" << endl; - out << indent() << "(void) a2;" << endl; + out << indent() << "(void) a1;" << '\n'; + out << indent() << "(void) a2;" << '\n'; } else { - out << indent() << "(void) a;" << endl; - out << indent() << "(void) b;" << endl; + out << indent() << "(void) a;" << '\n'; + out << indent() << "(void) b;" << '\n'; } } scope_down(out); - out << endl; + out << '\n'; } void t_cpp_generator::generate_struct_ostream_operator_decl(std::ostream& out, t_struct* tstruct) { out << "std::ostream& operator<<(std::ostream& out, const " << tstruct->get_name() - << "& obj);" << endl; - out << endl; + << "& obj);" << '\n'; + out << '\n'; } void t_cpp_generator::generate_struct_ostream_operator(std::ostream& out, t_struct* tstruct) { @@ -1723,12 +1810,12 @@ void t_cpp_generator::generate_struct_ostream_operator(std::ostream& out, t_stru // thrift defines this behavior out << "std::ostream& operator<<(std::ostream& out, const " << tstruct->get_name() - << "& obj)" << endl; + << "& obj)" << '\n'; scope_up(out); - out << indent() << "obj.printTo(out);" << endl - << indent() << "return out;" << endl; + out << indent() << "obj.printTo(out);" << '\n' + << indent() << "return out;" << '\n'; scope_down(out); - out << endl; + out << '\n'; } } @@ -1793,7 +1880,7 @@ void generate_fields(std::ostream& out, } generate_field(out, *it); - out << ";" << endl; + out << ";" << '\n'; } } } @@ -1804,17 +1891,17 @@ void generate_fields(std::ostream& out, void t_cpp_generator::generate_struct_print_method(std::ostream& out, t_struct* tstruct) { out << indent(); generate_struct_print_method_decl(out, tstruct); - out << " {" << endl; + out << " {" << '\n'; indent_up(); - out << indent() << "using ::apache::thrift::to_string;" << endl; - out << indent() << "out << \"" << tstruct->get_name() << "(\";" << endl; + out << indent() << "using ::apache::thrift::to_string;" << '\n'; + out << indent() << "out << \"" << tstruct->get_name() << "(\";" << '\n'; struct_ostream_operator_generator::generate_fields(out, tstruct->get_members(), indent()); - out << indent() << "out << \")\";" << endl; + out << indent() << "out << \")\";" << '\n'; indent_down(); - out << "}" << endl << endl; + out << "}" << '\n' << '\n'; } /** @@ -1823,29 +1910,29 @@ void t_cpp_generator::generate_struct_print_method(std::ostream& out, t_struct* void t_cpp_generator::generate_exception_what_method(std::ostream& out, t_struct* tstruct) { out << indent(); generate_exception_what_method_decl(out, tstruct, true); - out << " {" << endl; + out << " {" << '\n'; indent_up(); - out << indent() << "try {" << endl; + out << indent() << "try {" << '\n'; indent_up(); - out << indent() << "std::stringstream ss;" << endl; - out << indent() << "ss << \"TException - service has thrown: \" << *this;" << endl; - out << indent() << "this->thriftTExceptionMessageHolder_ = ss.str();" << endl; - out << indent() << "return this->thriftTExceptionMessageHolder_.c_str();" << endl; + out << indent() << "std::stringstream ss;" << '\n'; + out << indent() << "ss << \"TException - service has thrown: \" << *this;" << '\n'; + out << indent() << "this->thriftTExceptionMessageHolder_ = ss.str();" << '\n'; + out << indent() << "return this->thriftTExceptionMessageHolder_.c_str();" << '\n'; indent_down(); - out << indent() << "} catch (const std::exception&) {" << endl; + out << indent() << "} catch (const std::exception&) {" << '\n'; indent_up(); out << indent() << "return \"TException - service has thrown: " << tstruct->get_name() << "\";" - << endl; + << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; indent_down(); - out << "}" << endl << endl; + out << "}" << '\n' << '\n'; } /** @@ -1865,30 +1952,30 @@ void t_cpp_generator::generate_service(t_service* tservice) { // Print header file includes f_header_ << autogen_comment(); - f_header_ << "#ifndef " << svcname << "_H" << endl << "#define " << svcname << "_H" << endl - << endl; + f_header_ << "#ifndef " << svcname << "_H" << '\n' << "#define " << svcname << "_H" << '\n' + << '\n'; if (gen_cob_style_) { - f_header_ << "#include " << endl // TMemoryBuffer - << "#include " << endl - << "namespace apache { namespace thrift { namespace async {" << endl - << "class TAsyncChannel;" << endl << "}}}" << endl; + f_header_ << "#include " << '\n' // TMemoryBuffer + << "#include " << '\n' + << "namespace apache { namespace thrift { namespace async {" << '\n' + << "class TAsyncChannel;" << '\n' << "}}}" << '\n'; } - f_header_ << "#include " << endl; + f_header_ << "#include " << '\n'; if (gen_cob_style_) { - f_header_ << "#include " << endl; + f_header_ << "#include " << '\n'; } - f_header_ << "#include " << endl; - f_header_ << "#include " << endl; + f_header_ << "#include " << '\n'; + f_header_ << "#include " << '\n'; f_header_ << "#include \"" << get_include_prefix(*get_program()) << program_name_ << "_types.h\"" - << endl; + << '\n'; t_service* extends_service = tservice->get_extends(); if (extends_service != nullptr) { f_header_ << "#include \"" << get_include_prefix(*(extends_service->get_program())) - << extends_service->get_name() << ".h\"" << endl; + << extends_service->get_name() << ".h\"" << '\n'; } - f_header_ << endl << ns_open_ << endl << endl; + f_header_ << '\n' << ns_open_ << '\n' << '\n'; f_header_ << "#ifdef _MSC_VER\n" " #pragma warning( push )\n" @@ -1899,30 +1986,30 @@ void t_cpp_generator::generate_service(t_service* tservice) { string f_service_name = get_out_dir() + svcname + ".cpp"; f_service_.open(f_service_name.c_str()); f_service_ << autogen_comment(); - f_service_ << "#include \"" << get_include_prefix(*get_program()) << svcname << ".h\"" << endl; + f_service_ << "#include \"" << get_include_prefix(*get_program()) << svcname << ".h\"" << '\n'; if (gen_cob_style_) { - f_service_ << "#include \"thrift/async/TAsyncChannel.h\"" << endl; + f_service_ << "#include \"thrift/async/TAsyncChannel.h\"" << '\n'; } if (gen_templates_) { f_service_ << "#include \"" << get_include_prefix(*get_program()) << svcname << ".tcc\"" - << endl; + << '\n'; string f_service_tcc_name = get_out_dir() + svcname + ".tcc"; f_service_tcc_.open(f_service_tcc_name.c_str()); f_service_tcc_ << autogen_comment(); f_service_tcc_ << "#include \"" << get_include_prefix(*get_program()) << svcname << ".h\"" - << endl; + << '\n'; - f_service_tcc_ << "#ifndef " << svcname << "_TCC" << endl << "#define " << svcname << "_TCC" - << endl << endl; + f_service_tcc_ << "#ifndef " << svcname << "_TCC" << '\n' << "#define " << svcname << "_TCC" + << '\n' << '\n'; if (gen_cob_style_) { - f_service_tcc_ << "#include \"thrift/async/TAsyncChannel.h\"" << endl; + f_service_tcc_ << "#include \"thrift/async/TAsyncChannel.h\"" << '\n'; } } - f_service_ << endl << ns_open_ << endl << endl; - f_service_tcc_ << endl << ns_open_ << endl << endl; + f_service_ << '\n' << ns_open_ << '\n' << '\n'; + f_service_tcc_ << '\n' << ns_open_ << '\n' << '\n'; // Generate all the components generate_service_interface(tservice, ""); @@ -1959,19 +2046,19 @@ void t_cpp_generator::generate_service(t_service* tservice) { "#endif\n\n"; // Close the namespace - f_service_ << ns_close_ << endl << endl; - f_service_tcc_ << ns_close_ << endl << endl; - f_header_ << ns_close_ << endl << endl; + f_service_ << ns_close_ << '\n' << '\n'; + f_service_tcc_ << ns_close_ << '\n' << '\n'; + f_header_ << ns_close_ << '\n' << '\n'; // TODO(simpkins): Make this a separate option if (gen_templates_) { - f_header_ << "#include \"" << get_include_prefix(*get_program()) << svcname << ".tcc\"" << endl + f_header_ << "#include \"" << get_include_prefix(*get_program()) << svcname << ".tcc\"" << '\n' << "#include \"" << get_include_prefix(*get_program()) << program_name_ - << "_types.tcc\"" << endl << endl; + << "_types.tcc\"" << '\n' << '\n'; } - f_header_ << "#endif" << endl; - f_service_tcc_ << "#endif" << endl; + f_header_ << "#endif" << '\n'; + f_service_tcc_ << "#endif" << '\n'; // Close the files f_service_tcc_.close(); @@ -2000,9 +2087,10 @@ void t_cpp_generator::generate_service_helpers(t_service* tservice) { generate_struct_definition(out, f_service_, ts, false); generate_struct_reader(out, ts); generate_struct_writer(out, ts); + ts->set_name(tservice->get_name() + "_" + (*f_iter)->get_name() + "_pargs"); generate_struct_declaration(f_header_, ts, false, true, false, true); - generate_struct_definition(out, f_service_, ts, false); + generate_struct_definition(out, f_service_, ts, false, false, true); generate_struct_writer(out, ts, true); ts->set_name(name_orig); @@ -2024,9 +2112,9 @@ void t_cpp_generator::generate_service_interface(t_service* tservice, string sty if (gen_templates_) { client_name += "T"; service_if_name += "T"; - indent(f_header_) << "template " << endl; + indent(f_header_) << "template " << '\n'; } - indent(f_header_) << "class " << client_name << ";" << endl << endl; + indent(f_header_) << "class " << client_name << ";" << '\n' << '\n'; } string extends = ""; @@ -2040,31 +2128,31 @@ void t_cpp_generator::generate_service_interface(t_service* tservice, string sty } if (style == "CobCl" && gen_templates_) { - f_header_ << "template " << endl; + f_header_ << "template " << '\n'; } generate_java_doc(f_header_, tservice); - f_header_ << "class " << service_if_name << extends << " {" << endl << " public:" << endl; + f_header_ << "class " << service_if_name << extends << " {" << '\n' << " public:" << '\n'; indent_up(); - f_header_ << indent() << "virtual ~" << service_if_name << "() {}" << endl; + f_header_ << indent() << "virtual ~" << service_if_name << "() {}" << '\n'; vector functions = tservice->get_functions(); vector::iterator f_iter; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { if ((*f_iter)->has_doc()) - f_header_ << endl; + f_header_ << '\n'; generate_java_doc(f_header_, *f_iter); - f_header_ << indent() << "virtual " << function_signature(*f_iter, style) << " = 0;" << endl; + f_header_ << indent() << "virtual " << function_signature(*f_iter, style) << " = 0;" << '\n'; } indent_down(); - f_header_ << "};" << endl << endl; + f_header_ << "};" << '\n' << '\n'; if (style == "CobCl" && gen_templates_) { // generate a backwards-compatible typedef for clients that do not // know about the new template-style code f_header_ << "typedef " << service_if_name << "< ::apache::thrift::protocol::TProtocol> " - << service_name_ << style << "If;" << endl << endl; + << service_name_ << style << "If;" << '\n' << '\n'; } } @@ -2107,37 +2195,37 @@ void t_cpp_generator::generate_service_interface_factory(t_service* tservice, st extends = " : virtual public " + type_name(tservice->get_extends()) + style + "IfFactory"; } - f_header_ << "class " << factory_name << extends << " {" << endl << " public:" << endl; + f_header_ << "class " << factory_name << extends << " {" << '\n' << " public:" << '\n'; indent_up(); - f_header_ << indent() << "typedef " << service_if_name << " Handler;" << endl << endl << indent() - << "virtual ~" << factory_name << "() {}" << endl << endl << indent() << "virtual " + f_header_ << indent() << "typedef " << service_if_name << " Handler;" << '\n' << '\n' << indent() + << "virtual ~" << factory_name << "() {}" << '\n' << '\n' << indent() << "virtual " << service_if_name << "* getHandler(" << "const ::apache::thrift::TConnectionInfo& connInfo)" - << (extends.empty() ? "" : " override") << " = 0;" << endl << indent() + << (extends.empty() ? "" : " override") << " = 0;" << '\n' << indent() << "virtual void releaseHandler(" << base_if_name << "* /* handler */)" - << (extends.empty() ? "" : " override") << " = 0;" << endl << indent(); + << (extends.empty() ? "" : " override") << " = 0;" << '\n' << indent(); indent_down(); - f_header_ << "};" << endl << endl; + f_header_ << "};" << '\n' << '\n'; // Generate the singleton factory class string singleton_factory_name = service_if_name + "SingletonFactory"; f_header_ << "class " << singleton_factory_name << " : virtual public " << factory_name << " {" - << endl << " public:" << endl; + << '\n' << " public:" << '\n'; indent_up(); 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 " + << ">& iface) : iface_(iface) {}" << '\n' << indent() << "virtual ~" + << singleton_factory_name << "() {}" << '\n' << '\n' << indent() << "virtual " << service_if_name << "* getHandler(" - << "const ::apache::thrift::TConnectionInfo&) override {" << endl << indent() - << " return iface_.get();" << endl << indent() << "}" << endl << indent() - << "virtual void releaseHandler(" << base_if_name << "* /* handler */) override {}" << endl; + << "const ::apache::thrift::TConnectionInfo&) override {" << '\n' << indent() + << " return iface_.get();" << '\n' << indent() << "}" << '\n' << indent() + << "virtual void releaseHandler(" << base_if_name << "* /* handler */) override {}" << '\n'; - f_header_ << endl << " protected:" << endl << indent() << "::std::shared_ptr<" << service_if_name - << "> iface_;" << endl; + f_header_ << '\n' << " protected:" << '\n' << indent() << "::std::shared_ptr<" << service_if_name + << "> iface_;" << '\n'; indent_down(); - f_header_ << "};" << endl << endl; + f_header_ << "};" << '\n' << '\n'; } /** @@ -2151,14 +2239,14 @@ void t_cpp_generator::generate_service_null(t_service* tservice, string style) { extends = " , virtual public " + type_name(tservice->get_extends()) + style + "Null"; } f_header_ << "class " << service_name_ << style << "Null : virtual public " << service_name_ - << style << "If" << extends << " {" << endl << " public:" << endl; + << style << "If" << extends << " {" << '\n' << " public:" << '\n'; indent_up(); - f_header_ << indent() << "virtual ~" << service_name_ << style << "Null() {}" << endl; + f_header_ << indent() << "virtual ~" << service_name_ << style << "Null() {}" << '\n'; vector functions = tservice->get_functions(); vector::iterator f_iter; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { f_header_ << indent() << function_signature(*f_iter, style, "", false) - << " override {" << endl; + << " override {" << '\n'; indent_up(); t_type* returntype = (*f_iter)->get_returntype(); @@ -2166,18 +2254,18 @@ void t_cpp_generator::generate_service_null(t_service* tservice, string style) { if (style == "") { if (returntype->is_void() || is_complex_type(returntype)) { - f_header_ << indent() << "return;" << endl; + f_header_ << indent() << "return;" << '\n'; } else { - f_header_ << indent() << declare_field(&returnfield, true) << endl << indent() - << "return _return;" << endl; + f_header_ << indent() << declare_field(&returnfield, true) << '\n' << indent() + << "return _return;" << '\n'; } } else if (style == "CobSv") { if (returntype->is_void()) { - f_header_ << indent() << "return cob();" << endl; + f_header_ << indent() << "return cob();" << '\n'; } else { t_field returnfield(returntype, "_return"); - f_header_ << indent() << declare_field(&returnfield, true) << endl << indent() - << "return cob(_return);" << endl; + f_header_ << indent() << declare_field(&returnfield, true) << '\n' << indent() + << "return cob(_return);" << '\n'; } } else { @@ -2185,10 +2273,10 @@ void t_cpp_generator::generate_service_null(t_service* tservice, string style) { } indent_down(); - f_header_ << indent() << "}" << endl; + f_header_ << indent() << "}" << '\n'; } indent_down(); - f_header_ << "};" << endl << endl; + f_header_ << "};" << '\n' << '\n'; } void t_cpp_generator::generate_function_call(ostream& out, @@ -2219,7 +2307,7 @@ void t_cpp_generator::generate_function_call(ostream& out, } out << arg_prefix << (*f_iter)->get_name(); } - out << ");" << endl; + out << ");" << '\n'; } void t_cpp_generator::generate_service_async_skeleton(t_service* tservice) { @@ -2233,58 +2321,58 @@ void t_cpp_generator::generate_service_async_skeleton(t_service* tservice) { ofstream_with_content_based_conditional_update f_skeleton; f_skeleton.open(f_skeleton_name.c_str()); f_skeleton << "// This autogenerated skeleton file illustrates one way to adapt a synchronous" - << endl << "// interface into an asynchronous interface. You should copy it to another" - << endl + << '\n' << "// interface into an asynchronous interface. You should copy it to another" + << '\n' << "// filename to avoid overwriting it and rewrite as asynchronous any functions" - << endl << "// that would otherwise introduce unwanted latency." << endl << endl - << "#include \"" << get_include_prefix(*get_program()) << svcname << ".h\"" << endl - << "#include " << endl - << "#include " << endl - << "#include " << endl - << "#include " << endl - << "#include " << endl << endl - << "using namespace ::apache::thrift;" << endl - << "using namespace ::apache::thrift::protocol;" << endl - << "using namespace ::apache::thrift::transport;" << endl - << "using namespace ::apache::thrift::async;" << endl << endl; + << '\n' << "// that would otherwise introduce unwanted latency." << '\n' << '\n' + << "#include \"" << get_include_prefix(*get_program()) << svcname << ".h\"" << '\n' + << "#include " << '\n' + << "#include " << '\n' + << "#include " << '\n' + << "#include " << '\n' + << "#include " << '\n' << '\n' + << "using namespace ::apache::thrift;" << '\n' + << "using namespace ::apache::thrift::protocol;" << '\n' + << "using namespace ::apache::thrift::transport;" << '\n' + << "using namespace ::apache::thrift::async;" << '\n' << '\n'; // the following code would not compile: // using namespace ; // using namespace ::; if ((!ns.empty()) && (ns.compare(" ::") != 0)) { - f_skeleton << "using namespace " << string(ns, 0, ns.size() - 2) << ";" << endl << endl; + f_skeleton << "using namespace " << string(ns, 0, ns.size() - 2) << ";" << '\n' << '\n'; } - f_skeleton << "class " << svcname << "Handler : virtual public " << svcname << "If {" << endl - << " public:" << endl; + f_skeleton << "class " << svcname << "Handler : virtual public " << svcname << "If {" << '\n' + << " public:" << '\n'; indent_up(); - f_skeleton << indent() << svcname << "Handler() {" << endl << indent() - << " // Your initialization goes here" << endl << indent() << "}" << endl << endl; + f_skeleton << indent() << svcname << "Handler() {" << '\n' << indent() + << " // Your initialization goes here" << '\n' << indent() << "}" << '\n' << '\n'; vector functions = tservice->get_functions(); vector::iterator f_iter; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { generate_java_doc(f_skeleton, *f_iter); - f_skeleton << indent() << function_signature(*f_iter, "") << " {" << endl << indent() - << " // Your implementation goes here" << endl << indent() << " printf(\"" - << (*f_iter)->get_name() << "\\n\");" << endl << indent() << "}" << endl << endl; + f_skeleton << indent() << function_signature(*f_iter, "") << " {" << '\n' << indent() + << " // Your implementation goes here" << '\n' << indent() << " printf(\"" + << (*f_iter)->get_name() << "\\n\");" << '\n' << indent() << "}" << '\n' << '\n'; } indent_down(); - f_skeleton << "};" << endl << endl; + f_skeleton << "};" << '\n' << '\n'; f_skeleton << "class " << svcname << "AsyncHandler : " - << "public " << svcname << "CobSvIf {" << endl << " public:" << endl; + << "public " << svcname << "CobSvIf {" << '\n' << " public:" << '\n'; indent_up(); - f_skeleton << indent() << svcname << "AsyncHandler() {" << endl << indent() + f_skeleton << indent() << svcname << "AsyncHandler() {" << '\n' << indent() << " syncHandler_ = std::unique_ptr<" << svcname << "Handler>(new " << svcname - << "Handler);" << endl << indent() << " // Your initialization goes here" << endl - << indent() << "}" << endl; - f_skeleton << indent() << "virtual ~" << service_name_ << "AsyncHandler();" << endl; + << "Handler);" << '\n' << indent() << " // Your initialization goes here" << '\n' + << indent() << "}" << '\n'; + f_skeleton << indent() << "virtual ~" << service_name_ << "AsyncHandler();" << '\n'; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { - f_skeleton << endl << indent() << function_signature(*f_iter, "CobSv", "", true) << " {" - << endl; + f_skeleton << '\n' << indent() << function_signature(*f_iter, "CobSv", "", true) << " {" + << '\n'; indent_up(); t_type* returntype = (*f_iter)->get_returntype(); @@ -2292,32 +2380,32 @@ void t_cpp_generator::generate_service_async_skeleton(t_service* tservice) { string target = returntype->is_void() ? "" : "_return"; if (!returntype->is_void()) { - f_skeleton << indent() << declare_field(&returnfield, true) << endl; + f_skeleton << indent() << declare_field(&returnfield, true) << '\n'; } generate_function_call(f_skeleton, *f_iter, target, "syncHandler_", ""); - f_skeleton << indent() << "return cob(" << target << ");" << endl; + f_skeleton << indent() << "return cob(" << target << ");" << '\n'; scope_down(f_skeleton); } - f_skeleton << endl << " protected:" << endl << indent() << "std::unique_ptr<" << svcname - << "Handler> syncHandler_;" << endl; + f_skeleton << '\n' << " protected:" << '\n' << indent() << "std::unique_ptr<" << svcname + << "Handler> syncHandler_;" << '\n'; indent_down(); - f_skeleton << "};" << endl << endl; + f_skeleton << "};" << '\n' << '\n'; - f_skeleton << indent() << "int main(int argc, char **argv) {" << endl; + f_skeleton << indent() << "int main(int argc, char **argv) {" << '\n'; indent_up(); f_skeleton - << indent() << "int port = 9090;" << endl << indent() << "::std::shared_ptr<" << svcname - << "AsyncHandler> handler(new " << svcname << "AsyncHandler());" << endl << indent() - << "::std::shared_ptr<" << svcname << "AsyncProcessor> processor(new " << svcname << "AsyncProcessor(handler));" << endl + << indent() << "int port = 9090;" << '\n' << indent() << "::std::shared_ptr<" << svcname + << "AsyncHandler> handler(new " << svcname << "AsyncHandler());" << '\n' << indent() + << "::std::shared_ptr<" << svcname << "AsyncProcessor> processor(new " << svcname << "AsyncProcessor(handler));" << '\n' << indent() << "::std::shared_ptr protocolFactory(new TBinaryProtocolFactory());" - << endl + << '\n' << indent() << "::std::shared_ptr protocolProcessor(new TAsyncProtocolProcessor(processor, protocolFactory));" - << endl << endl << indent() + << '\n' << '\n' << indent() << "TEvhttpServer server(protocolProcessor, port);" - << endl << indent() << "server.serve();" << endl << indent() << "return 0;" << endl; + << '\n' << indent() << "server.serve();" << '\n' << indent() << "return 0;" << '\n'; indent_down(); - f_skeleton << "}" << endl << endl; + f_skeleton << "}" << '\n' << '\n'; } /** @@ -2343,35 +2431,35 @@ void t_cpp_generator::generate_service_multiface(t_service* tservice) { // Generate the header portion f_header_ << "class " << service_name_ << "Multiface : " - << "virtual public " << service_name_ << "If" << extends_multiface << " {" << endl - << " public:" << endl; + << "virtual public " << service_name_ << "If" << extends_multiface << " {" << '\n' + << " public:" << '\n'; indent_up(); f_header_ << indent() << service_name_ << "Multiface(" << list_type - << "& ifaces) : ifaces_(ifaces) {" << endl; + << "& ifaces) : ifaces_(ifaces) {" << '\n'; if (!extends.empty()) { f_header_ << indent() << " std::vector >::iterator iter;" - << endl << indent() << " for (iter = ifaces.begin(); iter != ifaces.end(); ++iter) {" - << endl << indent() << " " << extends << "Multiface::add(*iter);" << endl - << indent() << " }" << endl; + << '\n' << indent() << " for (iter = ifaces.begin(); iter != ifaces.end(); ++iter) {" + << '\n' << indent() << " " << extends << "Multiface::add(*iter);" << '\n' + << indent() << " }" << '\n'; } - f_header_ << indent() << "}" << endl << indent() << "virtual ~" << service_name_ - << "Multiface() {}" << endl; + f_header_ << indent() << "}" << '\n' << indent() << "virtual ~" << service_name_ + << "Multiface() {}" << '\n'; indent_down(); // Protected data members - f_header_ << " protected:" << endl; + f_header_ << " protected:" << '\n'; indent_up(); - f_header_ << indent() << list_type << " ifaces_;" << endl << indent() << service_name_ - << "Multiface() {}" << endl << indent() << "void add(::std::shared_ptr<" - << service_name_ << "If> iface) {" << endl; + f_header_ << indent() << list_type << " ifaces_;" << '\n' << indent() << service_name_ + << "Multiface() {}" << '\n' << indent() << "void add(::std::shared_ptr<" + << service_name_ << "If> iface) {" << '\n'; if (!extends.empty()) { - f_header_ << indent() << " " << extends << "Multiface::add(iface);" << endl; + f_header_ << indent() << " " << extends << "Multiface::add(iface);" << '\n'; } - f_header_ << indent() << " ifaces_.push_back(iface);" << endl << indent() << "}" << endl; + f_header_ << indent() << " ifaces_.push_back(iface);" << '\n' << indent() << "}" << '\n'; indent_down(); - f_header_ << indent() << " public:" << endl; + f_header_ << indent() << " public:" << '\n'; indent_up(); for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { @@ -2396,31 +2484,31 @@ void t_cpp_generator::generate_service_multiface(t_service* tservice) { } call += ")"; - f_header_ << indent() << function_signature(*f_iter, "") << " override {" << endl; + f_header_ << indent() << function_signature(*f_iter, "") << " override {" << '\n'; indent_up(); - f_header_ << indent() << "size_t sz = ifaces_.size();" << endl << indent() << "size_t i = 0;" - << endl << indent() << "for (; i < (sz - 1); ++i) {" << endl; + f_header_ << indent() << "size_t sz = ifaces_.size();" << '\n' << indent() << "size_t i = 0;" + << '\n' << indent() << "for (; i < (sz - 1); ++i) {" << '\n'; indent_up(); - f_header_ << indent() << call << ";" << endl; + f_header_ << indent() << call << ";" << '\n'; indent_down(); - f_header_ << indent() << "}" << endl; + f_header_ << indent() << "}" << '\n'; if (!(*f_iter)->get_returntype()->is_void()) { if (is_complex_type((*f_iter)->get_returntype())) { - f_header_ << indent() << call << ";" << endl << indent() << "return;" << endl; + f_header_ << indent() << call << ";" << '\n' << indent() << "return;" << '\n'; } else { - f_header_ << indent() << "return " << call << ";" << endl; + f_header_ << indent() << "return " << call << ";" << '\n'; } } else { - f_header_ << indent() << call << ";" << endl; + f_header_ << indent() << call << ";" << '\n'; } indent_down(); - f_header_ << indent() << "}" << endl << endl; + f_header_ << indent() << "}" << '\n' << '\n'; } indent_down(); - f_header_ << indent() << "};" << endl << endl; + f_header_ << indent() << "};" << '\n' << '\n'; } /** @@ -2471,7 +2559,7 @@ void t_cpp_generator::generate_service_client(t_service* tservice, string style) f_header_ << template_header << "class " << service_name_ << style << "Client" << short_suffix << " : " << "virtual public " << service_name_ << ifstyle << if_suffix << extends_client << " {" - << endl << " public:" << endl; + << '\n' << " public:" << '\n'; indent_up(); if (style != "Cob") { @@ -2484,18 +2572,18 @@ void t_cpp_generator::generate_service_client(t_service* tservice, string style) if (extends.empty()) { if (style == "Concurrent") { - f_header_ << ": sync_(sync)" << endl; + f_header_ << ": sync_(sync)" << '\n'; } - f_header_ << "{" << endl; - f_header_ << indent() << " setProtocol" << short_suffix << "(prot);" << endl << indent() - << "}" << endl; + f_header_ << "{" << '\n'; + f_header_ << indent() << " setProtocol" << short_suffix << "(prot);" << '\n' << indent() + << "}" << '\n'; } else { - f_header_ << ":" << endl; + f_header_ << ":" << '\n'; f_header_ << indent() << " " << extends << style << client_suffix << "(prot, prot"; if (style == "Concurrent") { f_header_ << ", sync"; } - f_header_ << ") {}" << endl; + f_header_ << ") {}" << '\n'; } f_header_ << indent() << service_name_ << style << "Client" << short_suffix << "(" << prot_ptr @@ -2504,41 +2592,41 @@ void t_cpp_generator::generate_service_client(t_service* tservice, string style) 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_ << ": sync_(sync)" << '\n'; } - f_header_ << "{" << endl; - f_header_ << indent() << " setProtocol" << short_suffix << "(iprot,oprot);" << endl - << indent() << "}" << endl; + f_header_ << "{" << '\n'; + f_header_ << indent() << " setProtocol" << short_suffix << "(iprot,oprot);" << '\n' + << indent() << "}" << '\n'; } else { f_header_ << ":" << indent() << " " << extends << style << client_suffix << "(iprot, oprot"; if (style == "Concurrent") { f_header_ << ", sync"; } - f_header_ << ") {}" << endl; + f_header_ << ") {}" << '\n'; } // create the setProtocol methods if (extends.empty()) { - f_header_ << " private:" << endl; + f_header_ << " private:" << '\n'; // 1: one parameter f_header_ << indent() << "void setProtocol" << short_suffix << "(" << prot_ptr << " prot) {" - << endl; - f_header_ << indent() << "setProtocol" << short_suffix << "(prot,prot);" << endl; - f_header_ << indent() << "}" << endl; + << '\n'; + f_header_ << indent() << "setProtocol" << short_suffix << "(prot,prot);" << '\n'; + f_header_ << indent() << "}" << '\n'; // 2: two parameter f_header_ << indent() << "void setProtocol" << short_suffix << "(" << prot_ptr << " iprot, " - << prot_ptr << " oprot) {" << endl; + << prot_ptr << " oprot) {" << '\n'; - f_header_ << indent() << " piprot_=iprot;" << endl << indent() << " poprot_=oprot;" << endl - << indent() << " iprot_ = iprot.get();" << endl << indent() - << " oprot_ = oprot.get();" << endl; + f_header_ << indent() << " piprot_=iprot;" << '\n' << indent() << " poprot_=oprot;" << '\n' + << indent() << " iprot_ = iprot.get();" << '\n' << indent() + << " oprot_ = oprot.get();" << '\n'; - f_header_ << indent() << "}" << endl; - f_header_ << " public:" << endl; + f_header_ << indent() << "}" << '\n'; + f_header_ << " public:" << '\n'; } // Generate getters for the protocols. @@ -2546,45 +2634,45 @@ void t_cpp_generator::generate_service_client(t_service* tservice, string style) // TODO(simpkins): should they be templated? f_header_ << indent() << "std::shared_ptr< ::apache::thrift::protocol::TProtocol> getInputProtocol() {" - << endl << indent() << " return " << _this << "piprot_;" << endl << indent() << "}" - << endl; + << '\n' << indent() << " return " << _this << "piprot_;" << '\n' << indent() << "}" + << '\n'; f_header_ << indent() << "std::shared_ptr< ::apache::thrift::protocol::TProtocol> getOutputProtocol() {" - << endl << indent() << " return " << _this << "poprot_;" << endl << indent() << "}" - << endl; + << '\n' << indent() << " return " << _this << "poprot_;" << '\n' << indent() << "}" + << '\n'; } else /* if (style == "Cob") */ { f_header_ << indent() << service_name_ << style << "Client" << short_suffix << "(" << "std::shared_ptr< ::apache::thrift::async::TAsyncChannel> channel, " - << "::apache::thrift::protocol::TProtocolFactory* protocolFactory) :" << endl; + << "::apache::thrift::protocol::TProtocolFactory* protocolFactory) :" << '\n'; if (extends.empty()) { - f_header_ << indent() << " channel_(channel)," << endl << indent() - << " itrans_(new ::apache::thrift::transport::TMemoryBuffer())," << endl + f_header_ << indent() << " channel_(channel)," << '\n' << indent() + << " itrans_(new ::apache::thrift::transport::TMemoryBuffer())," << '\n' << indent() << " otrans_(new ::apache::thrift::transport::TMemoryBuffer())," - << endl; + << '\n'; 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_(::std::dynamic_pointer_cast(" - << "protocolFactory->getProtocol(itrans_)))," << endl << indent() + << "protocolFactory->getProtocol(itrans_)))," << '\n' << indent() << " poprot_(::std::dynamic_pointer_cast(" - << "protocolFactory->getProtocol(otrans_))) {" << endl; + << "protocolFactory->getProtocol(otrans_))) {" << '\n'; // Throw a TException if either dynamic cast failed. - f_header_ << indent() << " if (!piprot_ || !poprot_) {" << endl << indent() + f_header_ << indent() << " if (!piprot_ || !poprot_) {" << '\n' << indent() << " throw ::apache::thrift::TException(\"" << "TProtocolFactory returned unexpected protocol type in " << service_name_ - << style << "Client" << short_suffix << " constructor\");" << endl << indent() - << " }" << endl; + << style << "Client" << short_suffix << " constructor\");" << '\n' << indent() + << " }" << '\n'; } else { - f_header_ << indent() << " piprot_(protocolFactory->getProtocol(itrans_))," << endl - << indent() << " poprot_(protocolFactory->getProtocol(otrans_)) {" << endl; + f_header_ << indent() << " piprot_(protocolFactory->getProtocol(itrans_))," << '\n' + << indent() << " poprot_(protocolFactory->getProtocol(otrans_)) {" << '\n'; } - f_header_ << indent() << " iprot_ = piprot_.get();" << endl << indent() - << " oprot_ = poprot_.get();" << endl << indent() << "}" << endl; + f_header_ << indent() << " iprot_ = piprot_.get();" << '\n' << indent() + << " oprot_ = poprot_.get();" << '\n' << indent() << "}" << '\n'; } else { f_header_ << indent() << " " << extends << style << client_suffix - << "(channel, protocolFactory) {}" << endl; + << "(channel, protocolFactory) {}" << '\n'; } } @@ -2592,10 +2680,10 @@ void t_cpp_generator::generate_service_client(t_service* tservice, string style) generate_java_doc(f_header_, tservice); f_header_ << indent() - << "::std::shared_ptr< ::apache::thrift::async::TAsyncChannel> getChannel() {" << endl - << indent() << " return " << _this << "channel_;" << endl << indent() << "}" << endl; + << "::std::shared_ptr< ::apache::thrift::async::TAsyncChannel> getChannel() {" << '\n' + << indent() << " return " << _this << "channel_;" << '\n' << indent() << "}" << '\n'; if (!gen_no_client_completion_) { - f_header_ << indent() << "virtual void completed__(bool /* success */) {}" << endl; + f_header_ << indent() << "virtual void completed__(bool /* success */) {}" << '\n'; } } @@ -2603,8 +2691,8 @@ void t_cpp_generator::generate_service_client(t_service* tservice, string style) vector::const_iterator f_iter; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { generate_java_doc(f_header_, *f_iter); - indent(f_header_) << function_signature(*f_iter, ifstyle) - << " override;" << endl; + indent(f_header_) << function_signature(*f_iter, ifstyle) + << " override;" << '\n'; // TODO(dreiss): Use private inheritance to avoid generating thise in cob-style. if (style == "Concurrent" && !(*f_iter)->is_oneway()) { // concurrent clients need to move the seqid from the send function to the @@ -2613,12 +2701,12 @@ void t_cpp_generator::generate_service_client(t_service* tservice, string style) t_function send_function(g_type_i32, /*returning seqid*/ string("send_") + (*f_iter)->get_name(), (*f_iter)->get_arglist()); - indent(f_header_) << function_signature(&send_function, "") << ";" << endl; + indent(f_header_) << function_signature(&send_function, "") << ";" << '\n'; } else { t_function send_function(g_type_void, string("send_") + (*f_iter)->get_name(), (*f_iter)->get_arglist()); - indent(f_header_) << function_signature(&send_function, "") << ";" << endl; + indent(f_header_) << function_signature(&send_function, "") << ";" << '\n'; } if (!(*f_iter)->is_oneway()) { if (style == "Concurrent") { @@ -2628,52 +2716,52 @@ void t_cpp_generator::generate_service_client(t_service* tservice, string style) t_function recv_function((*f_iter)->get_returntype(), string("recv_") + (*f_iter)->get_name(), &seqIdArgStruct); - indent(f_header_) << function_signature(&recv_function, "") << ";" << endl; + indent(f_header_) << function_signature(&recv_function, "") << ";" << '\n'; } else { t_struct noargs(program_); t_function recv_function((*f_iter)->get_returntype(), string("recv_") + (*f_iter)->get_name(), &noargs); - indent(f_header_) << function_signature(&recv_function, "") << ";" << endl; + indent(f_header_) << function_signature(&recv_function, "") << ";" << '\n'; } } } indent_down(); if (extends.empty()) { - f_header_ << " protected:" << endl; + f_header_ << " protected:" << '\n'; indent_up(); if (style == "Cob") { f_header_ << indent() - << "::std::shared_ptr< ::apache::thrift::async::TAsyncChannel> channel_;" << endl + << "::std::shared_ptr< ::apache::thrift::async::TAsyncChannel> channel_;" << '\n' << indent() - << "::std::shared_ptr< ::apache::thrift::transport::TMemoryBuffer> itrans_;" << endl + << "::std::shared_ptr< ::apache::thrift::transport::TMemoryBuffer> itrans_;" << '\n' << indent() << "::std::shared_ptr< ::apache::thrift::transport::TMemoryBuffer> otrans_;" - << endl; + << '\n'; } f_header_ << - indent() << prot_ptr << " piprot_;" << endl << - indent() << prot_ptr << " poprot_;" << endl << - indent() << protocol_type << "* iprot_;" << endl << - indent() << protocol_type << "* oprot_;" << endl; + indent() << prot_ptr << " piprot_;" << '\n' << + indent() << prot_ptr << " poprot_;" << '\n' << + indent() << protocol_type << "* iprot_;" << '\n' << + indent() << protocol_type << "* oprot_;" << '\n'; if (style == "Concurrent") { f_header_ << - indent() << "std::shared_ptr< ::apache::thrift::async::TConcurrentClientSyncInfo> sync_;"< sync_;" << '\n'; } indent_down(); } - f_header_ << "};" << endl << endl; + f_header_ << "};" << '\n' << '\n'; if (gen_templates_) { // Output a backwards compatibility typedef using // TProtocol as the template parameter. f_header_ << "typedef " << service_name_ << style << "ClientT< ::apache::thrift::protocol::TProtocol> " << service_name_ << style - << "Client;" << endl << endl; + << "Client;" << '\n' << '\n'; } string scope = service_name_ + style + client_suffix + "::"; @@ -2695,7 +2783,7 @@ void t_cpp_generator::generate_service_client(t_service* tservice, string style) if (gen_templates_) { indent(out) << template_header; } - indent(out) << function_signature(*f_iter, ifstyle, scope) << endl; + indent(out) << function_signature(*f_iter, ifstyle, scope) << '\n'; scope_up(out); indent(out) << seqIdCapture << "send_" << funname << "("; @@ -2714,33 +2802,33 @@ void t_cpp_generator::generate_service_client(t_service* tservice, string style) } out << (*fld_iter)->get_name(); } - out << ");" << endl; + out << ");" << '\n'; if (style != "Cob") { if (!(*f_iter)->is_oneway()) { out << indent(); if (!(*f_iter)->get_returntype()->is_void()) { if (is_complex_type((*f_iter)->get_returntype())) { - out << "recv_" << funname << "(_return" << seqIdCommaUse << ");" << endl; + out << "recv_" << funname << "(_return" << seqIdCommaUse << ");" << '\n'; } else { - out << "return recv_" << funname << "(" << seqIdUse << ");" << endl; + out << "return recv_" << funname << "(" << seqIdUse << ");" << '\n'; } } else { - out << "recv_" << funname << "(" << seqIdUse << ");" << endl; + out << "recv_" << funname << "(" << seqIdUse << ");" << '\n'; } } } else { if (!(*f_iter)->is_oneway()) { out << indent() << _this << "channel_->sendAndRecvMessage(" << "::std::bind(cob, this), " << _this << "otrans_.get(), " << _this << "itrans_.get());" - << endl; + << '\n'; } else { out << indent() << _this << "channel_->sendMessage(" - << "::std::bind(cob, this), " << _this << "otrans_.get());" << endl; + << "::std::bind(cob, this), " << _this << "otrans_.get());" << '\n'; } } scope_down(out); - out << endl; + out << '\n'; // if (style != "Cob") // TODO(dreiss): Libify the client and don't generate this for cob-style if (true) { @@ -2757,7 +2845,7 @@ void t_cpp_generator::generate_service_client(t_service* tservice, string style) if (gen_templates_) { indent(out) << template_header; } - indent(out) << function_signature(&send_function, "", scope) << endl; + indent(out) << function_signature(&send_function, "", scope) << '\n'; scope_up(out); // Function arguments and results @@ -2772,41 +2860,41 @@ void t_cpp_generator::generate_service_client(t_service* tservice, string style) } // Serialize the request out << - indent() << "int32_t cseqid = " << cseqidVal << ";" << endl; + indent() << "int32_t cseqid = " << cseqidVal << ";" << '\n'; if(style == "Concurrent") { out << - indent() << "::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());" << endl; + indent() << "::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());" << '\n'; } if (style == "Cob") { out << - indent() << _this << "otrans_->resetBuffer();" << endl; + indent() << _this << "otrans_->resetBuffer();" << '\n'; } out << indent() << _this << "oprot_->writeMessageBegin(\"" << (*f_iter)->get_name() << "\", ::apache::thrift::protocol::" << ((*f_iter)->is_oneway() ? "T_ONEWAY" : "T_CALL") << - ", cseqid);" << endl << endl << - indent() << argsname << " args;" << endl; + ", cseqid);" << '\n' << '\n' << + indent() << argsname << " args;" << '\n'; for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) { out << indent() << "args." << (*fld_iter)->get_name() << " = &" << (*fld_iter)->get_name() - << ";" << endl; + << ";" << '\n'; } - out << indent() << "args.write(" << _this << "oprot_);" << endl << endl << indent() << _this - << "oprot_->writeMessageEnd();" << endl << indent() << _this - << "oprot_->getTransport()->writeEnd();" << endl << indent() << _this - << "oprot_->getTransport()->flush();" << endl; + out << indent() << "args.write(" << _this << "oprot_);" << '\n' << '\n' << indent() << _this + << "oprot_->writeMessageEnd();" << '\n' << indent() << _this + << "oprot_->getTransport()->writeEnd();" << '\n' << indent() << _this + << "oprot_->getTransport()->flush();" << '\n'; if (style == "Concurrent") { - out << endl << indent() << "sentry.commit();" << endl; + out << '\n' << indent() << "sentry.commit();" << '\n'; if (!(*f_iter)->is_oneway()) { - out << indent() << "return cseqid;" << endl; + out << indent() << "return cseqid;" << '\n'; } } scope_down(out); - out << endl; + out << '\n'; // Generate recv function only if not an oneway function if (!(*f_iter)->is_oneway()) { @@ -2828,124 +2916,123 @@ void t_cpp_generator::generate_service_client(t_service* tservice, string style) if (gen_templates_) { indent(out) << template_header; } - indent(out) << function_signature(&recv_function, "", scope) << endl; + indent(out) << function_signature(&recv_function, "", scope) << '\n'; scope_up(out); - out << endl << - indent() << "int32_t rseqid = 0;" << endl << - indent() << "std::string fname;" << endl << - indent() << "::apache::thrift::protocol::TMessageType mtype;" << endl; + out << '\n' << + indent() << "int32_t rseqid = 0;" << '\n' << + indent() << "std::string fname;" << '\n' << + indent() << "::apache::thrift::protocol::TMessageType mtype;" << '\n'; if(style == "Concurrent") { - out << - 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_.get(), seqid);" << endl; + out << '\n' << + indent() << "// the read mutex gets dropped and reacquired as part of waitForWork()" << '\n' << + indent() << "// The destructor of this sentry wakes up other clients" << '\n' << + indent() << "::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);" << '\n'; } if (style == "Cob" && !gen_no_client_completion_) { - out << indent() << "bool completed = false;" << endl << endl << indent() << "try {"; + out << indent() << "bool completed = false;" << '\n' << '\n' << indent() << "try {"; indent_up(); } - out << endl; + out << '\n'; if (style == "Concurrent") { out << - indent() << "while(true) {" << endl << - indent() << " if(!this->sync_->getPending(fname, mtype, rseqid)) {" << endl; + indent() << "while(true) {" << '\n' << + indent() << " if(!this->sync_->getPending(fname, mtype, rseqid)) {" << '\n'; indent_up(); indent_up(); } out << - indent() << _this << "iprot_->readMessageBegin(fname, mtype, rseqid);" << endl; + indent() << _this << "iprot_->readMessageBegin(fname, mtype, rseqid);" << '\n'; if (style == "Concurrent") { scope_down(out); - out << indent() << "if(seqid == rseqid) {" << endl; + out << indent() << "if(seqid == rseqid) {" << '\n'; indent_up(); } out << - indent() << "if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {" << endl << - indent() << " ::apache::thrift::TApplicationException x;" << endl << - indent() << " x.read(" << _this << "iprot_);" << endl << - indent() << " " << _this << "iprot_->readMessageEnd();" << endl << - indent() << " " << _this << "iprot_->getTransport()->readEnd();" << endl; + indent() << "if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {" << '\n' << + indent() << " ::apache::thrift::TApplicationException x;" << '\n' << + indent() << " x.read(" << _this << "iprot_);" << '\n' << + indent() << " " << _this << "iprot_->readMessageEnd();" << '\n' << + indent() << " " << _this << "iprot_->getTransport()->readEnd();" << '\n'; if (style == "Cob" && !gen_no_client_completion_) { - out << indent() << " completed = true;" << endl << indent() << " completed__(true);" - << endl; + out << indent() << " completed = true;" << '\n' << indent() << " completed__(true);" + << '\n'; } if (style == "Concurrent") { - out << indent() << " sentry.commit();" << endl; + out << indent() << " sentry.commit();" << '\n'; } out << - indent() << " throw x;" << endl << - indent() << "}" << endl << - indent() << "if (mtype != ::apache::thrift::protocol::T_REPLY) {" << endl << - indent() << " " << _this << "iprot_->skip(" << "::apache::thrift::protocol::T_STRUCT);" << endl << - indent() << " " << _this << "iprot_->readMessageEnd();" << endl << - indent() << " " << _this << "iprot_->getTransport()->readEnd();" << endl; + indent() << " throw x;" << '\n' << + indent() << "}" << '\n' << + indent() << "if (mtype != ::apache::thrift::protocol::T_REPLY) {" << '\n' << + indent() << " " << _this << "iprot_->skip(" << "::apache::thrift::protocol::T_STRUCT);" << '\n' << + indent() << " " << _this << "iprot_->readMessageEnd();" << '\n' << + indent() << " " << _this << "iprot_->getTransport()->readEnd();" << '\n'; if (style == "Cob" && !gen_no_client_completion_) { - out << indent() << " completed = true;" << endl << indent() << " completed__(false);" - << endl; + out << indent() << " completed = true;" << '\n' << indent() << " completed__(false);" + << '\n'; } out << - indent() << "}" << endl << - indent() << "if (fname.compare(\"" << (*f_iter)->get_name() << "\") != 0) {" << endl << - indent() << " " << _this << "iprot_->skip(" << "::apache::thrift::protocol::T_STRUCT);" << endl << - indent() << " " << _this << "iprot_->readMessageEnd();" << endl << - indent() << " " << _this << "iprot_->getTransport()->readEnd();" << endl; + indent() << "}" << '\n' << + indent() << "if (fname.compare(\"" << (*f_iter)->get_name() << "\") != 0) {" << '\n' << + indent() << " " << _this << "iprot_->skip(" << "::apache::thrift::protocol::T_STRUCT);" << '\n' << + indent() << " " << _this << "iprot_->readMessageEnd();" << '\n' << + indent() << " " << _this << "iprot_->getTransport()->readEnd();" << '\n'; if (style == "Cob" && !gen_no_client_completion_) { - out << indent() << " completed = true;" << endl << indent() << " completed__(false);" - << endl; + out << indent() << " completed = true;" << '\n' << indent() << " completed__(false);" + << '\n'; } if (style == "Concurrent") { - out << endl << - indent() << " // in a bad state, don't commit" << endl << - indent() << " using ::apache::thrift::protocol::TProtocolException;" << endl << - indent() << " throw TProtocolException(TProtocolException::INVALID_DATA);" << endl; + out << '\n' << + indent() << " // in a bad state, don't commit" << '\n' << + indent() << " using ::apache::thrift::protocol::TProtocolException;" << '\n' << + indent() << " throw TProtocolException(TProtocolException::INVALID_DATA);" << '\n'; } - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; if (!(*f_iter)->get_returntype()->is_void() && !is_complex_type((*f_iter)->get_returntype())) { t_field returnfield((*f_iter)->get_returntype(), "_return"); - out << indent() << declare_field(&returnfield) << endl; + out << indent() << declare_field(&returnfield) << '\n'; } - out << indent() << resultname << " result;" << endl; + out << indent() << resultname << " result;" << '\n'; if (!(*f_iter)->get_returntype()->is_void()) { - out << indent() << "result.success = &_return;" << endl; + out << indent() << "result.success = &_return;" << '\n'; } - out << indent() << "result.read(" << _this << "iprot_);" << endl << indent() << _this - << "iprot_->readMessageEnd();" << endl << indent() << _this - << "iprot_->getTransport()->readEnd();" << endl << endl; + out << indent() << "result.read(" << _this << "iprot_);" << '\n' << indent() << _this + << "iprot_->readMessageEnd();" << '\n' << indent() << _this + << "iprot_->getTransport()->readEnd();" << '\n' << '\n'; // Careful, only look for _result if not a void function if (!(*f_iter)->get_returntype()->is_void()) { if (is_complex_type((*f_iter)->get_returntype())) { out << - indent() << "if (result.__isset.success) {" << endl; + indent() << "if (result.__isset.success) {" << '\n'; out << - indent() << " // _return pointer has now been filled" << endl; + indent() << " // _return pointer has now been filled" << '\n'; if (style == "Cob" && !gen_no_client_completion_) { - out << indent() << " completed = true;" << endl << indent() << " completed__(true);" - << endl; + out << indent() << " completed = true;" << '\n' << indent() << " completed__(true);" + << '\n'; } if (style == "Concurrent") { - out << indent() << " sentry.commit();" << endl; + out << indent() << " sentry.commit();" << '\n'; } out << - indent() << " return;" << endl << - indent() << "}" << endl; + indent() << " return;" << '\n' << + indent() << "}" << '\n'; } else { - out << indent() << "if (result.__isset.success) {" << endl; + out << indent() << "if (result.__isset.success) {" << '\n'; if (style == "Cob" && !gen_no_client_completion_) { - out << indent() << " completed = true;" << endl << indent() << " completed__(true);" - << endl; + out << indent() << " completed = true;" << '\n' << indent() << " completed__(true);" + << '\n'; } if (style == "Concurrent") { - out << indent() << " sentry.commit();" << endl; + out << indent() << " sentry.commit();" << '\n'; } - out << indent() << " return _return;" << endl << indent() << "}" << endl; + out << indent() << " return _return;" << '\n' << indent() << "}" << '\n'; } } @@ -2953,62 +3040,62 @@ void t_cpp_generator::generate_service_client(t_service* tservice, string style) const std::vector& xceptions = xs->get_members(); vector::const_iterator x_iter; for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { - out << indent() << "if (result.__isset." << (*x_iter)->get_name() << ") {" << endl; + out << indent() << "if (result.__isset." << (*x_iter)->get_name() << ") {" << '\n'; if (style == "Cob" && !gen_no_client_completion_) { - out << indent() << " completed = true;" << endl << indent() << " completed__(true);" - << endl; + out << indent() << " completed = true;" << '\n' << indent() << " completed__(true);" + << '\n'; } if (style == "Concurrent") { - out << indent() << " sentry.commit();" << endl; + out << indent() << " sentry.commit();" << '\n'; } - out << indent() << " throw result." << (*x_iter)->get_name() << ";" << endl << indent() - << "}" << endl; + out << indent() << " throw result." << (*x_iter)->get_name() << ";" << '\n' << indent() + << "}" << '\n'; } // We only get here if we are a void function if ((*f_iter)->get_returntype()->is_void()) { if (style == "Cob" && !gen_no_client_completion_) { - out << indent() << "completed = true;" << endl << indent() << "completed__(true);" - << endl; + out << indent() << "completed = true;" << '\n' << indent() << "completed__(true);" + << '\n'; } if (style == "Concurrent") { - out << indent() << "sentry.commit();" << endl; + out << indent() << "sentry.commit();" << '\n'; } - indent(out) << "return;" << endl; + indent(out) << "return;" << '\n'; } else { if (style == "Cob" && !gen_no_client_completion_) { - out << indent() << "completed = true;" << endl << indent() << "completed__(true);" - << endl; + out << indent() << "completed = true;" << '\n' << indent() << "completed__(true);" + << '\n'; } if (style == "Concurrent") { - out << indent() << "// in a bad state, don't commit" << endl; + out << indent() << "// in a bad state, don't commit" << '\n'; } out << indent() << "throw " "::apache::thrift::TApplicationException(::apache::thrift::" "TApplicationException::MISSING_RESULT, \"" << (*f_iter)->get_name() - << " failed: unknown result\");" << endl; + << " failed: unknown result\");" << '\n'; } if (style == "Concurrent") { indent_down(); indent_down(); - out << - indent() << " }" << endl << - indent() << " // seqid != 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() << "} // end while(true)" << endl; + out << indent() << " }" << '\n' + << indent() << " // seqid != rseqid" << '\n' + << indent() << " this->sync_->updatePending(fname, mtype, rseqid);" << '\n' + << '\n' + << indent() + << " // this will temporarily unlock the readMutex, and let other clients get work done" << '\n' + << indent() << " this->sync_->waitForWork(seqid);" << '\n' + << indent() << "} // end while(true)" << '\n'; } if (style == "Cob" && !gen_no_client_completion_) { indent_down(); - out << indent() << "} catch (...) {" << endl << indent() << " if (!completed) {" << endl - << indent() << " completed__(false);" << endl << indent() << " }" << endl - << indent() << " throw;" << endl << indent() << "}" << endl; + out << indent() << "} catch (...) {" << '\n' << indent() << " if (!completed) {" << '\n' + << indent() << " completed__(false);" << '\n' << indent() << " }" << '\n' + << indent() << " throw;" << '\n' << indent() << "}" << '\n'; } // Close function scope_down(out); - out << endl; + out << '\n'; } } } @@ -3144,61 +3231,61 @@ void ProcessorGenerator::generate_class_definition() { // Generate the header portion f_header_ << template_header_ << "class " << class_name_ << " : public " << parent_class << " {" - << endl; + << '\n'; // Protected data members - f_header_ << " protected:" << endl; + f_header_ << " protected:" << '\n'; indent_up(); - f_header_ << indent() << "::std::shared_ptr<" << if_name_ << "> iface_;" << endl; + f_header_ << indent() << "::std::shared_ptr<" << if_name_ << "> iface_;" << '\n'; f_header_ << indent() << "virtual " << ret_type_ << "dispatchCall(" << finish_cob_ << "::apache::thrift::protocol::TProtocol* iprot, " << "::apache::thrift::protocol::TProtocol* oprot, " - << "const std::string& fname, int32_t seqid" << call_context_ - << ") override;" << endl; + << "const std::string& fname, int32_t seqid" << call_context_ + << ") override;" << '\n'; if (generator_->gen_templates_) { f_header_ << indent() << "virtual " << ret_type_ << "dispatchCallTemplated(" << finish_cob_ << "Protocol_* iprot, Protocol_* oprot, " - << "const std::string& fname, int32_t seqid" << call_context_ << ");" << endl; + << "const std::string& fname, int32_t seqid" << call_context_ << ");" << '\n'; } indent_down(); // Process function declarations - f_header_ << " private:" << endl; + f_header_ << " private:" << '\n'; indent_up(); // Declare processMap_ f_header_ << indent() << "typedef void (" << class_name_ << "::*" << "ProcessFunction)(" << finish_cob_decl_ << "int32_t, " << "::apache::thrift::protocol::TProtocol*, " - << "::apache::thrift::protocol::TProtocol*" << call_context_decl_ << ");" << endl; + << "::apache::thrift::protocol::TProtocol*" << call_context_decl_ << ");" << '\n'; if (generator_->gen_templates_) { f_header_ << indent() << "typedef void (" << class_name_ << "::*" << "SpecializedProcessFunction)(" << finish_cob_decl_ << "int32_t, " - << "Protocol_*, Protocol_*" << call_context_decl_ << ");" << endl << indent() - << "struct ProcessFunctions {" << endl << indent() << " ProcessFunction generic;" - << endl << indent() << " SpecializedProcessFunction specialized;" << endl << indent() + << "Protocol_*, Protocol_*" << call_context_decl_ << ");" << '\n' << indent() + << "struct ProcessFunctions {" << '\n' << indent() << " ProcessFunction generic;" + << '\n' << indent() << " SpecializedProcessFunction specialized;" << '\n' << indent() << " ProcessFunctions(ProcessFunction g, " - << "SpecializedProcessFunction s) :" << endl << indent() << " generic(g)," << endl - << indent() << " specialized(s) {}" << endl << indent() + << "SpecializedProcessFunction s) :" << '\n' << indent() << " generic(g)," << '\n' + << indent() << " specialized(s) {}" << '\n' << indent() << " ProcessFunctions() : generic(nullptr), specialized(nullptr) " - << "{}" << endl << indent() << "};" << endl << indent() + << "{}" << '\n' << indent() << "};" << '\n' << indent() << "typedef std::map " - << "ProcessMap;" << endl; + << "ProcessMap;" << '\n'; } else { f_header_ << indent() << "typedef std::map " - << "ProcessMap;" << endl; + << "ProcessMap;" << '\n'; } - f_header_ << indent() << "ProcessMap processMap_;" << endl; + f_header_ << indent() << "ProcessMap processMap_;" << '\n'; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { indent(f_header_) << "void process_" << (*f_iter)->get_name() << "(" << finish_cob_ << "int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, " "::apache::thrift::protocol::TProtocol* oprot" << call_context_ << ");" - << endl; + << '\n'; if (generator_->gen_templates_) { indent(f_header_) << "void process_" << (*f_iter)->get_name() << "(" << finish_cob_ << "int32_t seqid, Protocol_* iprot, Protocol_* oprot" << call_context_ - << ");" << endl; + << ");" << '\n'; } if (style_ == "Cob") { // XXX Factor this out, even if it is a pain. @@ -3208,56 +3295,56 @@ void ProcessorGenerator::generate_class_definition() { f_header_ << indent() << "void return_" << (*f_iter)->get_name() << "(::std::function cob, int32_t seqid, " << "::apache::thrift::protocol::TProtocol* oprot, " - << "void* ctx" << ret_arg << ");" << endl; + << "void* ctx" << ret_arg << ");" << '\n'; if (generator_->gen_templates_) { f_header_ << indent() << "void return_" << (*f_iter)->get_name() << "(::std::function cob, int32_t seqid, " - << "Protocol_* oprot, void* ctx" << ret_arg << ");" << endl; + << "Protocol_* oprot, void* ctx" << ret_arg << ");" << '\n'; } // XXX Don't declare throw if it doesn't exist f_header_ << indent() << "void throw_" << (*f_iter)->get_name() << "(::std::function cob, int32_t seqid, " << "::apache::thrift::protocol::TProtocol* oprot, void* ctx, " - << "::apache::thrift::TDelayedException* _throw);" << endl; + << "::apache::thrift::TDelayedException* _throw);" << '\n'; if (generator_->gen_templates_) { f_header_ << indent() << "void throw_" << (*f_iter)->get_name() << "(::std::function cob, int32_t seqid, " << "Protocol_* oprot, void* ctx, " - << "::apache::thrift::TDelayedException* _throw);" << endl; + << "::apache::thrift::TDelayedException* _throw);" << '\n'; } } } - f_header_ << " public:" << endl << indent() << class_name_ << "(::std::shared_ptr<" << if_name_ - << "> iface) :" << endl; + f_header_ << " public:" << '\n' << indent() << class_name_ << "(::std::shared_ptr<" << if_name_ + << "> iface) :" << '\n'; if (!extends_.empty()) { - f_header_ << indent() << " " << extends_ << "(iface)," << endl; + f_header_ << indent() << " " << extends_ << "(iface)," << '\n'; } - f_header_ << indent() << " iface_(iface) {" << endl; + f_header_ << indent() << " iface_(iface) {" << '\n'; indent_up(); for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { f_header_ << indent() << "processMap_[\"" << (*f_iter)->get_name() << "\"] = "; if (generator_->gen_templates_) { - f_header_ << "ProcessFunctions(" << endl; + f_header_ << "ProcessFunctions(" << '\n'; if (generator_->gen_templates_only_) { - indent(f_header_) << " nullptr," << endl; + indent(f_header_) << " nullptr," << '\n'; } else { indent(f_header_) << " &" << class_name_ << "::process_" << (*f_iter)->get_name() << "," - << endl; + << '\n'; } indent(f_header_) << " &" << class_name_ << "::process_" << (*f_iter)->get_name() << ")"; } else { f_header_ << "&" << class_name_ << "::process_" << (*f_iter)->get_name(); } - f_header_ << ";" << endl; + f_header_ << ";" << '\n'; } indent_down(); - f_header_ << indent() << "}" << endl << endl << indent() << "virtual ~" << class_name_ << "() {}" - << endl; + f_header_ << indent() << "}" << '\n' << '\n' << indent() << "virtual ~" << class_name_ << "() {}" + << '\n'; indent_down(); - f_header_ << "};" << endl << endl; + f_header_ << "};" << '\n' << '\n'; if (generator_->gen_templates_) { // Generate a backwards compatible typedef, for callers who don't know @@ -3270,7 +3357,7 @@ void ProcessorGenerator::generate_class_definition() { // Therefore, we define TDummyProtocol solely so we can use it as the // template parameter here. f_header_ << "typedef " << class_name_ << "< ::apache::thrift::protocol::TDummyProtocol > " - << service_name_ << pstyle_ << "Processor;" << endl << endl; + << service_name_ << pstyle_ << "Processor;" << '\n' << '\n'; } } @@ -3292,32 +3379,32 @@ void ProcessorGenerator::generate_dispatch_call(bool template_protocol) { f_out_ << template_header_ << ret_type_ << class_name_ << template_suffix_ << "::dispatchCall" << function_suffix << "(" << finish_cob_ << protocol << "* iprot, " << protocol << "* oprot, " - << "const std::string& fname, int32_t seqid" << call_context_ << ") {" << endl; + << "const std::string& fname, int32_t seqid" << call_context_ << ") {" << '\n'; indent_up(); // HOT: member function pointer map - f_out_ << indent() << typename_str_ << "ProcessMap::iterator pfn;" << endl << indent() - << "pfn = processMap_.find(fname);" << endl << indent() - << "if (pfn == processMap_.end()) {" << endl; + f_out_ << indent() << typename_str_ << "ProcessMap::iterator pfn;" << '\n' << indent() + << "pfn = processMap_.find(fname);" << '\n' << indent() + << "if (pfn == processMap_.end()) {" << '\n'; if (extends_.empty()) { - f_out_ << indent() << " iprot->skip(::apache::thrift::protocol::T_STRUCT);" << endl << indent() - << " iprot->readMessageEnd();" << endl << indent() - << " iprot->getTransport()->readEnd();" << endl << indent() + f_out_ << indent() << " iprot->skip(::apache::thrift::protocol::T_STRUCT);" << '\n' << indent() + << " iprot->readMessageEnd();" << '\n' << indent() + << " iprot->getTransport()->readEnd();" << '\n' << indent() << " ::apache::thrift::TApplicationException " "x(::apache::thrift::TApplicationException::UNKNOWN_METHOD, \"Invalid method name: " - "'\"+fname+\"'\");" << endl << indent() + "'\"+fname+\"'\");" << '\n' << indent() << " oprot->writeMessageBegin(fname, ::apache::thrift::protocol::T_EXCEPTION, seqid);" - << endl << indent() << " x.write(oprot);" << endl << indent() - << " oprot->writeMessageEnd();" << endl << indent() - << " oprot->getTransport()->writeEnd();" << endl << indent() - << " oprot->getTransport()->flush();" << endl << indent() - << (style_ == "Cob" ? " return cob(true);" : " return true;") << endl; + << '\n' << indent() << " x.write(oprot);" << '\n' << indent() + << " oprot->writeMessageEnd();" << '\n' << indent() + << " oprot->getTransport()->writeEnd();" << '\n' << indent() + << " oprot->getTransport()->flush();" << '\n' << indent() + << (style_ == "Cob" ? " return cob(true);" : " return true;") << '\n'; } else { f_out_ << indent() << " return " << extends_ << "::dispatchCall(" << (style_ == "Cob" ? "cob, " : "") << "iprot, oprot, fname, seqid" << call_context_arg_ - << ");" << endl; + << ");" << '\n'; } - f_out_ << indent() << "}" << endl; + f_out_ << indent() << "}" << '\n'; if (template_protocol) { f_out_ << indent() << "(this->*(pfn->second.specialized))"; } else { @@ -3331,17 +3418,17 @@ void ProcessorGenerator::generate_dispatch_call(bool template_protocol) { f_out_ << indent() << "(this->*(pfn->second))"; } } - f_out_ << "(" << cob_arg_ << "seqid, iprot, oprot" << call_context_arg_ << ");" << endl; + f_out_ << "(" << cob_arg_ << "seqid, iprot, oprot" << call_context_arg_ << ");" << '\n'; // TODO(dreiss): return pfn ret? if (style_ == "Cob") { - f_out_ << indent() << "return;" << endl; + f_out_ << indent() << "return;" << '\n'; } else { - f_out_ << indent() << "return true;" << endl; + f_out_ << indent() << "return true;" << '\n'; } indent_down(); - f_out_ << "}" << endl << endl; + f_out_ << "}" << '\n' << '\n'; } void ProcessorGenerator::generate_process_functions() { @@ -3363,49 +3450,49 @@ void ProcessorGenerator::generate_factory() { // Generate the factory class definition f_header_ << template_header_ << "class " << factory_class_name_ << " : public ::apache::thrift::" << (style_ == "Cob" ? "async::TAsyncProcessorFactory" : "TProcessorFactory") << " {" - << endl << " public:" << endl; + << '\n' << " public:" << '\n'; indent_up(); f_header_ << indent() << factory_class_name_ << "(const ::std::shared_ptr< " << if_factory_name - << " >& handlerFactory) noexcept :" << endl << indent() - << " handlerFactory_(handlerFactory) {}" << endl << endl << indent() + << " >& handlerFactory) noexcept :" << '\n' << indent() + << " handlerFactory_(handlerFactory) {}" << '\n' << '\n' << indent() << "::std::shared_ptr< ::apache::thrift::" << (style_ == "Cob" ? "async::TAsyncProcessor" : "TProcessor") << " > " << "getProcessor(const ::apache::thrift::TConnectionInfo& connInfo) override;" - << endl; + << '\n'; - f_header_ << endl << " protected:" << endl << indent() << "::std::shared_ptr< " - << if_factory_name << " > handlerFactory_;" << endl; + f_header_ << '\n' << " protected:" << '\n' << indent() << "::std::shared_ptr< " + << if_factory_name << " > handlerFactory_;" << '\n'; indent_down(); - f_header_ << "};" << endl << endl; + f_header_ << "};" << '\n' << '\n'; // If we are generating templates, output a typedef for the plain // factory name. if (generator_->gen_templates_) { f_header_ << "typedef " << factory_class_name_ << "< ::apache::thrift::protocol::TDummyProtocol > " << service_name_ << pstyle_ - << "ProcessorFactory;" << endl << endl; + << "ProcessorFactory;" << '\n' << '\n'; } // Generate the getProcessor() method 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; + << "const ::apache::thrift::TConnectionInfo& connInfo) {" << '\n'; indent_up(); f_out_ << indent() << "::apache::thrift::ReleaseHandler< " << if_factory_name - << " > cleanup(handlerFactory_);" << endl << indent() << "::std::shared_ptr< " + << " > cleanup(handlerFactory_);" << '\n' << indent() << "::std::shared_ptr< " << if_name_ << " > handler(" - << "handlerFactory_->getHandler(connInfo), cleanup);" << endl << indent() + << "handlerFactory_->getHandler(connInfo), cleanup);" << '\n' << indent() << "::std::shared_ptr< ::apache::thrift::" << (style_ == "Cob" ? "async::TAsyncProcessor" : "TProcessor") << " > " - << "processor(new " << class_name_ << template_suffix_ << "(handler));" << endl << indent() - << "return processor;" << endl; + << "processor(new " << class_name_ << template_suffix_ << "(handler));" << '\n' << indent() + << "return processor;" << '\n'; indent_down(); - f_out_ << indent() << "}" << endl << endl; + f_out_ << indent() << "}" << '\n' << '\n'; } /** @@ -3450,7 +3537,7 @@ void t_cpp_generator::generate_function_helpers(t_service* tservice, t_function* result.set_name(tservice->get_name() + "_" + tfunction->get_name() + "_presult"); generate_struct_declaration(f_header_, &result, false, true, true, gen_cob_style_); - generate_struct_definition(out, f_service_, &result, false); + generate_struct_definition(out, f_service_, &result, false, false, true); generate_struct_reader(out, &result, true); if (gen_cob_style_) { generate_struct_writer(out, &result, true); @@ -3487,45 +3574,45 @@ void t_cpp_generator::generate_process_function(t_service* tservice, if (style != "Cob") { // Open function if (gen_templates_) { - out << indent() << "template " << endl; + out << indent() << "template " << '\n'; } const bool unnamed_oprot_seqid = tfunction->is_oneway() && !(gen_templates_ && !specialized); out << "void " << tservice->get_name() << "Processor" << class_suffix << "::" << "process_" << tfunction->get_name() << "(" << "int32_t" << (unnamed_oprot_seqid ? ", " : " seqid, ") << prot_type << "* iprot, " << prot_type << "*" << (unnamed_oprot_seqid ? ", " : " oprot, ") << "void* callContext)" - << endl; + << '\n'; scope_up(out); string argsname = tservice->get_name() + "_" + tfunction->get_name() + "_args"; string resultname = tservice->get_name() + "_" + tfunction->get_name() + "_result"; if (tfunction->is_oneway() && !unnamed_oprot_seqid) { - out << indent() << "(void) seqid;" << endl << indent() << "(void) oprot;" << endl; + out << indent() << "(void) seqid;" << '\n' << indent() << "(void) oprot;" << '\n'; } - out << indent() << "void* ctx = nullptr;" << endl << indent() - << "if (this->eventHandler_.get() != nullptr) {" << endl << indent() + out << indent() << "void* ctx = nullptr;" << '\n' << indent() + << "if (this->eventHandler_.get() != nullptr) {" << '\n' << indent() << " ctx = this->eventHandler_->getContext(" << service_func_name << ", callContext);" - << endl << indent() << "}" << endl << indent() + << '\n' << indent() << "}" << '\n' << indent() << "::apache::thrift::TProcessorContextFreer freer(" - << "this->eventHandler_.get(), ctx, " << service_func_name << ");" << endl << endl - << indent() << "if (this->eventHandler_.get() != nullptr) {" << endl << indent() - << " this->eventHandler_->preRead(ctx, " << service_func_name << ");" << endl << indent() - << "}" << endl << endl << indent() << argsname << " args;" << endl << indent() - << "args.read(iprot);" << endl << indent() << "iprot->readMessageEnd();" << endl << indent() - << "uint32_t bytes = iprot->getTransport()->readEnd();" << endl << endl << indent() - << "if (this->eventHandler_.get() != nullptr) {" << endl << indent() - << " this->eventHandler_->postRead(ctx, " << service_func_name << ", bytes);" << endl - << indent() << "}" << endl << endl; + << "this->eventHandler_.get(), ctx, " << service_func_name << ");" << '\n' << '\n' + << indent() << "if (this->eventHandler_.get() != nullptr) {" << '\n' << indent() + << " this->eventHandler_->preRead(ctx, " << service_func_name << ");" << '\n' << indent() + << "}" << '\n' << '\n' << indent() << argsname << " args;" << '\n' << indent() + << "args.read(iprot);" << '\n' << indent() << "iprot->readMessageEnd();" << '\n' << indent() + << "uint32_t bytes = iprot->getTransport()->readEnd();" << '\n' << '\n' << indent() + << "if (this->eventHandler_.get() != nullptr) {" << '\n' << indent() + << " this->eventHandler_->postRead(ctx, " << service_func_name << ", bytes);" << '\n' + << indent() << "}" << '\n' << '\n'; // Declare result if (!tfunction->is_oneway()) { - out << indent() << resultname << " result;" << endl; + out << indent() << resultname << " result;" << '\n'; } // Try block for functions with exceptions - out << indent() << "try {" << endl; + out << indent() << "try {" << '\n'; indent_up(); // Generate the function call @@ -3549,11 +3636,11 @@ void t_cpp_generator::generate_process_function(t_service* tservice, } out << "args." << (*f_iter)->get_name(); } - out << ");" << endl; + out << ");" << '\n'; // Set isset on success field if (!tfunction->is_oneway() && !tfunction->get_returntype()->is_void()) { - out << indent() << "result.__isset.success = true;" << endl; + out << indent() << "result.__isset.success = true;" << '\n'; } indent_down(); @@ -3562,12 +3649,12 @@ void t_cpp_generator::generate_process_function(t_service* tservice, if (!tfunction->is_oneway()) { for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { out << " catch (" << type_name((*x_iter)->get_type()) << " &" << (*x_iter)->get_name() - << ") {" << endl; + << ") {" << '\n'; if (!tfunction->is_oneway()) { indent_up(); out << indent() << "result." << (*x_iter)->get_name() - << " = std::move(" << (*x_iter)->get_name() << ");" << endl - << indent() << "result.__isset." << (*x_iter)->get_name() << " = true;" << endl; + << " = std::move(" << (*x_iter)->get_name() << ");" << '\n' + << indent() << "result.__isset." << (*x_iter)->get_name() << " = true;" << '\n'; indent_down(); out << indent() << "}"; } else { @@ -3577,53 +3664,53 @@ void t_cpp_generator::generate_process_function(t_service* tservice, } if (!tfunction->is_oneway()) { - out << " catch (const std::exception& e) {" << endl; + out << " catch (const std::exception& e) {" << '\n'; } else { - out << " catch (const std::exception&) {" << endl; + out << " catch (const std::exception&) {" << '\n'; } indent_up(); - out << indent() << "if (this->eventHandler_.get() != nullptr) {" << endl << indent() - << " this->eventHandler_->handlerError(ctx, " << service_func_name << ");" << endl - << indent() << "}" << endl; + out << indent() << "if (this->eventHandler_.get() != nullptr) {" << '\n' << indent() + << " this->eventHandler_->handlerError(ctx, " << service_func_name << ");" << '\n' + << indent() << "}" << '\n'; if (!tfunction->is_oneway()) { - out << endl << indent() << "::apache::thrift::TApplicationException x(e.what());" << endl + out << '\n' << indent() << "::apache::thrift::TApplicationException x(e.what());" << '\n' << indent() << "oprot->writeMessageBegin(\"" << tfunction->get_name() - << "\", ::apache::thrift::protocol::T_EXCEPTION, seqid);" << endl << indent() - << "x.write(oprot);" << endl << indent() << "oprot->writeMessageEnd();" << endl - << indent() << "oprot->getTransport()->writeEnd();" << endl << indent() - << "oprot->getTransport()->flush();" << endl; + << "\", ::apache::thrift::protocol::T_EXCEPTION, seqid);" << '\n' << indent() + << "x.write(oprot);" << '\n' << indent() << "oprot->writeMessageEnd();" << '\n' + << indent() << "oprot->getTransport()->writeEnd();" << '\n' << indent() + << "oprot->getTransport()->flush();" << '\n'; } - out << indent() << "return;" << endl; + out << indent() << "return;" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; // Shortcut out here for oneway functions if (tfunction->is_oneway()) { - out << indent() << "if (this->eventHandler_.get() != nullptr) {" << endl << indent() - << " this->eventHandler_->asyncComplete(ctx, " << service_func_name << ");" << endl - << indent() << "}" << endl << endl << indent() << "return;" << endl; + out << indent() << "if (this->eventHandler_.get() != nullptr) {" << '\n' << indent() + << " this->eventHandler_->asyncComplete(ctx, " << service_func_name << ");" << '\n' + << indent() << "}" << '\n' << '\n' << indent() << "return;" << '\n'; indent_down(); - out << "}" << endl << endl; + out << "}" << '\n' << '\n'; return; } // Serialize the result into a struct - out << indent() << "if (this->eventHandler_.get() != nullptr) {" << endl << indent() - << " this->eventHandler_->preWrite(ctx, " << service_func_name << ");" << endl << indent() - << "}" << endl << endl << indent() << "oprot->writeMessageBegin(\"" << tfunction->get_name() - << "\", ::apache::thrift::protocol::T_REPLY, seqid);" << endl << indent() - << "result.write(oprot);" << endl << indent() << "oprot->writeMessageEnd();" << endl - << indent() << "bytes = oprot->getTransport()->writeEnd();" << endl << indent() - << "oprot->getTransport()->flush();" << endl << endl << indent() - << "if (this->eventHandler_.get() != nullptr) {" << endl << indent() - << " this->eventHandler_->postWrite(ctx, " << service_func_name << ", bytes);" << endl - << indent() << "}" << endl; + out << indent() << "if (this->eventHandler_.get() != nullptr) {" << '\n' << indent() + << " this->eventHandler_->preWrite(ctx, " << service_func_name << ");" << '\n' << indent() + << "}" << '\n' << '\n' << indent() << "oprot->writeMessageBegin(\"" << tfunction->get_name() + << "\", ::apache::thrift::protocol::T_REPLY, seqid);" << '\n' << indent() + << "result.write(oprot);" << '\n' << indent() << "oprot->writeMessageEnd();" << '\n' + << indent() << "bytes = oprot->getTransport()->writeEnd();" << '\n' << indent() + << "oprot->getTransport()->flush();" << '\n' << '\n' << indent() + << "if (this->eventHandler_.get() != nullptr) {" << '\n' << indent() + << " this->eventHandler_->postWrite(ctx, " << service_func_name << ", bytes);" << '\n' + << indent() << "}" << '\n'; // Close function scope_down(out); - out << endl; + out << '\n'; } // Cob style. @@ -3631,11 +3718,11 @@ void t_cpp_generator::generate_process_function(t_service* tservice, // Processor entry point. // TODO(edhall) update for callContext when TEventServer is ready if (gen_templates_) { - out << indent() << "template " << endl; + out << indent() << "template " << '\n'; } out << "void " << tservice->get_name() << "AsyncProcessor" << class_suffix << "::process_" << tfunction->get_name() << "(::std::function cob, int32_t seqid, " - << prot_type << "* iprot, " << prot_type << "* oprot)" << endl; + << prot_type << "* iprot, " << prot_type << "* oprot)" << '\n'; scope_up(out); // TODO(simpkins): we could try to consoldate this @@ -3643,55 +3730,55 @@ void t_cpp_generator::generate_process_function(t_service* tservice, if (gen_templates_ && !specialized) { // If these are instances of Protocol_, instead of any old TProtocol, // use the specialized process function instead. - out << indent() << "Protocol_* _iprot = dynamic_cast(iprot);" << endl << indent() - << "Protocol_* _oprot = dynamic_cast(oprot);" << endl << indent() - << "if (_iprot && _oprot) {" << endl << indent() << " return process_" - << tfunction->get_name() << "(cob, seqid, _iprot, _oprot);" << endl << indent() << "}" - << endl << indent() << "T_GENERIC_PROTOCOL(this, iprot, _iprot);" << endl << indent() - << "T_GENERIC_PROTOCOL(this, oprot, _oprot);" << endl << endl; + out << indent() << "Protocol_* _iprot = dynamic_cast(iprot);" << '\n' << indent() + << "Protocol_* _oprot = dynamic_cast(oprot);" << '\n' << indent() + << "if (_iprot && _oprot) {" << '\n' << indent() << " return process_" + << tfunction->get_name() << "(cob, seqid, _iprot, _oprot);" << '\n' << indent() << "}" + << '\n' << indent() << "T_GENERIC_PROTOCOL(this, iprot, _iprot);" << '\n' << indent() + << "T_GENERIC_PROTOCOL(this, oprot, _oprot);" << '\n' << '\n'; } if (tfunction->is_oneway()) { - out << indent() << "(void) seqid;" << endl << indent() << "(void) oprot;" << endl; + out << indent() << "(void) seqid;" << '\n' << indent() << "(void) oprot;" << '\n'; } - out << indent() << tservice->get_name() + "_" + tfunction->get_name() << "_args args;" << endl - << indent() << "void* ctx = nullptr;" << endl << indent() - << "if (this->eventHandler_.get() != nullptr) {" << endl << indent() - << " ctx = this->eventHandler_->getContext(" << service_func_name << ", nullptr);" << endl - << indent() << "}" << endl << indent() << "::apache::thrift::TProcessorContextFreer freer(" - << "this->eventHandler_.get(), ctx, " << service_func_name << ");" << endl << endl - << indent() << "try {" << endl; + out << indent() << tservice->get_name() + "_" + tfunction->get_name() << "_args args;" << '\n' + << indent() << "void* ctx = nullptr;" << '\n' << indent() + << "if (this->eventHandler_.get() != nullptr) {" << '\n' << indent() + << " ctx = this->eventHandler_->getContext(" << service_func_name << ", nullptr);" << '\n' + << indent() << "}" << '\n' << indent() << "::apache::thrift::TProcessorContextFreer freer(" + << "this->eventHandler_.get(), ctx, " << service_func_name << ");" << '\n' << '\n' + << indent() << "try {" << '\n'; indent_up(); - out << indent() << "if (this->eventHandler_.get() != nullptr) {" << endl << indent() - << " this->eventHandler_->preRead(ctx, " << service_func_name << ");" << endl << indent() - << "}" << endl << indent() << "args.read(iprot);" << endl << indent() - << "iprot->readMessageEnd();" << endl << indent() - << "uint32_t bytes = iprot->getTransport()->readEnd();" << endl << indent() - << "if (this->eventHandler_.get() != nullptr) {" << endl << indent() - << " this->eventHandler_->postRead(ctx, " << service_func_name << ", bytes);" << endl - << indent() << "}" << endl; + out << indent() << "if (this->eventHandler_.get() != nullptr) {" << '\n' << indent() + << " this->eventHandler_->preRead(ctx, " << service_func_name << ");" << '\n' << indent() + << "}" << '\n' << indent() << "args.read(iprot);" << '\n' << indent() + << "iprot->readMessageEnd();" << '\n' << indent() + << "uint32_t bytes = iprot->getTransport()->readEnd();" << '\n' << indent() + << "if (this->eventHandler_.get() != nullptr) {" << '\n' << indent() + << " this->eventHandler_->postRead(ctx, " << service_func_name << ", bytes);" << '\n' + << indent() << "}" << '\n'; scope_down(out); // TODO(dreiss): Handle TExceptions? Expose to server? - out << indent() << "catch (const std::exception&) {" << endl << indent() - << " if (this->eventHandler_.get() != nullptr) {" << endl << indent() - << " this->eventHandler_->handlerError(ctx, " << service_func_name << ");" << endl - << indent() << " }" << endl << indent() << " return cob(false);" << endl << indent() - << "}" << endl; + out << indent() << "catch (const std::exception&) {" << '\n' << indent() + << " if (this->eventHandler_.get() != nullptr) {" << '\n' << indent() + << " this->eventHandler_->handlerError(ctx, " << service_func_name << ");" << '\n' + << indent() << " }" << '\n' << indent() << " return cob(false);" << '\n' << indent() + << "}" << '\n'; if (tfunction->is_oneway()) { - out << indent() << "if (this->eventHandler_.get() != nullptr) {" << endl << indent() - << " this->eventHandler_->asyncComplete(ctx, " << service_func_name << ");" << endl - << indent() << "}" << endl; + out << indent() << "if (this->eventHandler_.get() != nullptr) {" << '\n' << indent() + << " this->eventHandler_->asyncComplete(ctx, " << service_func_name << ");" << '\n' + << indent() << "}" << '\n'; } // TODO(dreiss): Figure out a strategy for exceptions in async handlers. - out << indent() << "freer.unregister();" << endl; + out << indent() << "freer.unregister();" << '\n'; if (tfunction->is_oneway()) { // No return. Just hand off our cob. // TODO(dreiss): Call the cob immediately? out << indent() << "iface_->" << tfunction->get_name() << "(" - << "::std::bind(cob, true)" << endl; + << "::std::bind(cob, true)" << '\n'; indent_up(); indent_up(); } else { @@ -3707,38 +3794,38 @@ void t_cpp_generator::generate_process_function(t_service* tservice, out << indent() << "void (" << tservice->get_name() << "AsyncProcessor" << class_suffix << "::*return_fn)(::std::function " << "cob, int32_t seqid, " << prot_type << "* oprot, void* ctx" << ret_arg - << ") =" << endl; + << ") =" << '\n'; out << indent() << " &" << tservice->get_name() << "AsyncProcessor" << class_suffix - << "::return_" << tfunction->get_name() << ";" << endl; + << "::return_" << tfunction->get_name() << ";" << '\n'; if (!xceptions.empty()) { out << indent() << "void (" << tservice->get_name() << "AsyncProcessor" << class_suffix << "::*throw_fn)(::std::function " << "cob, int32_t seqid, " << prot_type << "* oprot, void* ctx, " - << "::apache::thrift::TDelayedException* _throw) =" << endl; + << "::apache::thrift::TDelayedException* _throw) =" << '\n'; out << indent() << " &" << tservice->get_name() << "AsyncProcessor" << class_suffix - << "::throw_" << tfunction->get_name() << ";" << endl; + << "::throw_" << tfunction->get_name() << ";" << '\n'; } - out << indent() << "iface_->" << tfunction->get_name() << "(" << endl; + out << indent() << "iface_->" << tfunction->get_name() << "(" << '\n'; indent_up(); indent_up(); out << indent() << "::std::bind(return_fn, this, cob, seqid, oprot, ctx" << ret_placeholder << ")"; if (!xceptions.empty()) { - out << ',' << endl << indent() << "::std::bind(throw_fn, this, cob, seqid, oprot, " + out << ',' << '\n' << indent() << "::std::bind(throw_fn, this, cob, seqid, oprot, " << "ctx, ::std::placeholders::_1)"; } } // XXX Whitespace cleanup. for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { - out << ',' << endl << indent() << "args." << (*f_iter)->get_name(); + out << ',' << '\n' << indent() << "args." << (*f_iter)->get_name(); } - out << ");" << endl; + out << ");" << '\n'; indent_down(); indent_down(); scope_down(out); - out << endl; + out << '\n'; // Normal return. if (!tfunction->is_oneway()) { @@ -3748,128 +3835,128 @@ void t_cpp_generator::generate_process_function(t_service* tservice, ret_arg_name = ", _return"; } if (gen_templates_) { - out << indent() << "template " << endl; + out << indent() << "template " << '\n'; } out << "void " << tservice->get_name() << "AsyncProcessor" << class_suffix << "::return_" << tfunction->get_name() << "(::std::function cob, int32_t seqid, " - << prot_type << "* oprot, void* ctx" << ret_arg_decl << ')' << endl; + << prot_type << "* oprot, void* ctx" << ret_arg_decl << ')' << '\n'; scope_up(out); if (gen_templates_ && !specialized) { // If oprot is a Protocol_ instance, // use the specialized return function instead. - out << indent() << "Protocol_* _oprot = dynamic_cast(oprot);" << endl - << indent() << "if (_oprot) {" << endl << indent() << " return return_" - << tfunction->get_name() << "(cob, seqid, _oprot, ctx" << ret_arg_name << ");" << endl - << indent() << "}" << endl << indent() << "T_GENERIC_PROTOCOL(this, oprot, _oprot);" - << endl << endl; + out << indent() << "Protocol_* _oprot = dynamic_cast(oprot);" << '\n' + << indent() << "if (_oprot) {" << '\n' << indent() << " return return_" + << tfunction->get_name() << "(cob, seqid, _oprot, ctx" << ret_arg_name << ");" << '\n' + << indent() << "}" << '\n' << indent() << "T_GENERIC_PROTOCOL(this, oprot, _oprot);" + << '\n' << '\n'; } out << indent() << tservice->get_name() << "_" << tfunction->get_name() << "_presult result;" - << endl; + << '\n'; if (!tfunction->get_returntype()->is_void()) { // The const_cast here is unfortunate, but it would be a pain to avoid, // and we only do a write with this struct, which is const-safe. out << indent() << "result.success = const_cast<" << type_name(tfunction->get_returntype()) - << "*>(&_return);" << endl << indent() << "result.__isset.success = true;" << endl; + << "*>(&_return);" << '\n' << indent() << "result.__isset.success = true;" << '\n'; } // Serialize the result into a struct - out << endl << indent() << "if (this->eventHandler_.get() != nullptr) {" << endl << indent() - << " ctx = this->eventHandler_->getContext(" << service_func_name << ", nullptr);" << endl - << indent() << "}" << endl << indent() + out << '\n' << indent() << "if (this->eventHandler_.get() != nullptr) {" << '\n' << indent() + << " ctx = this->eventHandler_->getContext(" << service_func_name << ", nullptr);" << '\n' + << indent() << "}" << '\n' << indent() << "::apache::thrift::TProcessorContextFreer freer(" - << "this->eventHandler_.get(), ctx, " << service_func_name << ");" << endl << endl - << indent() << "if (this->eventHandler_.get() != nullptr) {" << endl << indent() - << " this->eventHandler_->preWrite(ctx, " << service_func_name << ");" << endl - << indent() << "}" << endl << endl << indent() << "oprot->writeMessageBegin(\"" - << tfunction->get_name() << "\", ::apache::thrift::protocol::T_REPLY, seqid);" << endl - << indent() << "result.write(oprot);" << endl << indent() << "oprot->writeMessageEnd();" - << endl << indent() << "uint32_t bytes = oprot->getTransport()->writeEnd();" << endl - << indent() << "oprot->getTransport()->flush();" << endl << indent() - << "if (this->eventHandler_.get() != nullptr) {" << endl << indent() - << " this->eventHandler_->postWrite(ctx, " << service_func_name << ", bytes);" << endl - << indent() << "}" << endl << indent() << "return cob(true);" << endl; + << "this->eventHandler_.get(), ctx, " << service_func_name << ");" << '\n' << '\n' + << indent() << "if (this->eventHandler_.get() != nullptr) {" << '\n' << indent() + << " this->eventHandler_->preWrite(ctx, " << service_func_name << ");" << '\n' + << indent() << "}" << '\n' << '\n' << indent() << "oprot->writeMessageBegin(\"" + << tfunction->get_name() << "\", ::apache::thrift::protocol::T_REPLY, seqid);" << '\n' + << indent() << "result.write(oprot);" << '\n' << indent() << "oprot->writeMessageEnd();" + << '\n' << indent() << "uint32_t bytes = oprot->getTransport()->writeEnd();" << '\n' + << indent() << "oprot->getTransport()->flush();" << '\n' << indent() + << "if (this->eventHandler_.get() != nullptr) {" << '\n' << indent() + << " this->eventHandler_->postWrite(ctx, " << service_func_name << ", bytes);" << '\n' + << indent() << "}" << '\n' << indent() << "return cob(true);" << '\n'; scope_down(out); - out << endl; + out << '\n'; } // Exception return. if (!tfunction->is_oneway() && !xceptions.empty()) { if (gen_templates_) { - out << indent() << "template " << endl; + out << indent() << "template " << '\n'; } out << "void " << tservice->get_name() << "AsyncProcessor" << class_suffix << "::throw_" << tfunction->get_name() << "(::std::function cob, int32_t seqid, " << prot_type << "* oprot, void* ctx, " - << "::apache::thrift::TDelayedException* _throw)" << endl; + << "::apache::thrift::TDelayedException* _throw)" << '\n'; scope_up(out); if (gen_templates_ && !specialized) { // If oprot is a Protocol_ instance, // use the specialized throw function instead. - out << indent() << "Protocol_* _oprot = dynamic_cast(oprot);" << endl - << indent() << "if (_oprot) {" << endl << indent() << " return throw_" - << tfunction->get_name() << "(cob, seqid, _oprot, ctx, _throw);" << endl << indent() - << "}" << endl << indent() << "T_GENERIC_PROTOCOL(this, oprot, _oprot);" << endl - << endl; + out << indent() << "Protocol_* _oprot = dynamic_cast(oprot);" << '\n' + << indent() << "if (_oprot) {" << '\n' << indent() << " return throw_" + << tfunction->get_name() << "(cob, seqid, _oprot, ctx, _throw);" << '\n' << indent() + << "}" << '\n' << indent() << "T_GENERIC_PROTOCOL(this, oprot, _oprot);" << '\n' + << '\n'; } // Get the event handler context - out << endl << indent() << "if (this->eventHandler_.get() != nullptr) {" << endl << indent() - << " ctx = this->eventHandler_->getContext(" << service_func_name << ", nullptr);" << endl - << indent() << "}" << endl << indent() + out << '\n' << indent() << "if (this->eventHandler_.get() != nullptr) {" << '\n' << indent() + << " ctx = this->eventHandler_->getContext(" << service_func_name << ", nullptr);" << '\n' + << indent() << "}" << '\n' << indent() << "::apache::thrift::TProcessorContextFreer freer(" - << "this->eventHandler_.get(), ctx, " << service_func_name << ");" << endl << endl; + << "this->eventHandler_.get(), ctx, " << service_func_name << ");" << '\n' << '\n'; // Throw the TDelayedException, and catch the result out << indent() << tservice->get_name() << "_" << tfunction->get_name() << "_result result;" - << endl << endl << indent() << "try {" << endl; + << '\n' << '\n' << indent() << "try {" << '\n'; indent_up(); - out << indent() << "_throw->throw_it();" << endl << indent() << "return cob(false);" - << endl; // Is this possible? TBD. + out << indent() << "_throw->throw_it();" << '\n' << indent() << "return cob(false);" + << '\n'; // Is this possible? TBD. indent_down(); out << indent() << '}'; for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { out << " catch (" << type_name((*x_iter)->get_type()) << " &" << (*x_iter)->get_name() - << ") {" << endl; + << ") {" << '\n'; indent_up(); out << indent() << "result." << (*x_iter)->get_name() << " = " << (*x_iter)->get_name() - << ";" << endl << indent() << "result.__isset." << (*x_iter)->get_name() << " = true;" - << endl; + << ";" << '\n' << indent() << "result.__isset." << (*x_iter)->get_name() << " = true;" + << '\n'; scope_down(out); } // Handle the case where an undeclared exception is thrown - out << " catch (std::exception& e) {" << endl; + out << " catch (std::exception& e) {" << '\n'; indent_up(); - out << indent() << "if (this->eventHandler_.get() != nullptr) {" << endl << indent() - << " this->eventHandler_->handlerError(ctx, " << service_func_name << ");" << endl - << indent() << "}" << endl << endl << indent() - << "::apache::thrift::TApplicationException x(e.what());" << endl << indent() + out << indent() << "if (this->eventHandler_.get() != nullptr) {" << '\n' << indent() + << " this->eventHandler_->handlerError(ctx, " << service_func_name << ");" << '\n' + << indent() << "}" << '\n' << '\n' << indent() + << "::apache::thrift::TApplicationException x(e.what());" << '\n' << indent() << "oprot->writeMessageBegin(\"" << tfunction->get_name() - << "\", ::apache::thrift::protocol::T_EXCEPTION, seqid);" << endl << indent() - << "x.write(oprot);" << endl << indent() << "oprot->writeMessageEnd();" << endl - << indent() << "oprot->getTransport()->writeEnd();" << endl << indent() - << "oprot->getTransport()->flush();" << endl << + << "\", ::apache::thrift::protocol::T_EXCEPTION, seqid);" << '\n' << indent() + << "x.write(oprot);" << '\n' << indent() << "oprot->writeMessageEnd();" << '\n' + << indent() << "oprot->getTransport()->writeEnd();" << '\n' << indent() + << "oprot->getTransport()->flush();" << '\n' << // We pass true to the cob here, since we did successfully write a // response, even though it is an exception response. // It looks like the argument is currently ignored, anyway. - indent() << "return cob(true);" << endl; + indent() << "return cob(true);" << '\n'; scope_down(out); // Serialize the result into a struct - out << indent() << "if (this->eventHandler_.get() != nullptr) {" << endl << indent() - << " this->eventHandler_->preWrite(ctx, " << service_func_name << ");" << endl - << indent() << "}" << endl << endl << indent() << "oprot->writeMessageBegin(\"" - << tfunction->get_name() << "\", ::apache::thrift::protocol::T_REPLY, seqid);" << endl - << indent() << "result.write(oprot);" << endl << indent() << "oprot->writeMessageEnd();" - << endl << indent() << "uint32_t bytes = oprot->getTransport()->writeEnd();" << endl - << indent() << "oprot->getTransport()->flush();" << endl << indent() - << "if (this->eventHandler_.get() != nullptr) {" << endl << indent() - << " this->eventHandler_->postWrite(ctx, " << service_func_name << ", bytes);" << endl - << indent() << "}" << endl << indent() << "return cob(true);" << endl; + out << indent() << "if (this->eventHandler_.get() != nullptr) {" << '\n' << indent() + << " this->eventHandler_->preWrite(ctx, " << service_func_name << ");" << '\n' + << indent() << "}" << '\n' << '\n' << indent() << "oprot->writeMessageBegin(\"" + << tfunction->get_name() << "\", ::apache::thrift::protocol::T_REPLY, seqid);" << '\n' + << indent() << "result.write(oprot);" << '\n' << indent() << "oprot->writeMessageEnd();" + << '\n' << indent() << "uint32_t bytes = oprot->getTransport()->writeEnd();" << '\n' + << indent() << "oprot->getTransport()->flush();" << '\n' << indent() + << "if (this->eventHandler_.get() != nullptr) {" << '\n' << indent() + << " this->eventHandler_->postWrite(ctx, " << service_func_name << ", bytes);" << '\n' + << indent() << "}" << '\n' << indent() << "return cob(true);" << '\n'; scope_down(out); - out << endl; + out << '\n'; } // for each function } // cob style } @@ -3889,58 +3976,58 @@ void t_cpp_generator::generate_service_skeleton(t_service* tservice) { ofstream_with_content_based_conditional_update f_skeleton; f_skeleton.open(f_skeleton_name.c_str()); - f_skeleton << "// This autogenerated skeleton file illustrates how to build a server." << endl - << "// You should copy it to another filename to avoid overwriting it." << endl << endl - << "#include \"" << get_include_prefix(*get_program()) << svcname << ".h\"" << endl - << "#include " << endl - << "#include " << endl - << "#include " << endl - << "#include " << endl << endl - << "using namespace ::apache::thrift;" << endl - << "using namespace ::apache::thrift::protocol;" << endl - << "using namespace ::apache::thrift::transport;" << endl - << "using namespace ::apache::thrift::server;" << endl << endl; + f_skeleton << "// This autogenerated skeleton file illustrates how to build a server." << '\n' + << "// You should copy it to another filename to avoid overwriting it." << '\n' << '\n' + << "#include \"" << get_include_prefix(*get_program()) << svcname << ".h\"" << '\n' + << "#include " << '\n' + << "#include " << '\n' + << "#include " << '\n' + << "#include " << '\n' << '\n' + << "using namespace ::apache::thrift;" << '\n' + << "using namespace ::apache::thrift::protocol;" << '\n' + << "using namespace ::apache::thrift::transport;" << '\n' + << "using namespace ::apache::thrift::server;" << '\n' << '\n'; // the following code would not compile: // using namespace ; // using namespace ::; if ((!ns.empty()) && (ns.compare(" ::") != 0)) { - f_skeleton << "using namespace " << string(ns, 0, ns.size() - 2) << ";" << endl << endl; + f_skeleton << "using namespace " << string(ns, 0, ns.size() - 2) << ";" << '\n' << '\n'; } - f_skeleton << "class " << svcname << "Handler : virtual public " << svcname << "If {" << endl - << " public:" << endl; + f_skeleton << "class " << svcname << "Handler : virtual public " << svcname << "If {" << '\n' + << " public:" << '\n'; indent_up(); - f_skeleton << indent() << svcname << "Handler() {" << endl << indent() - << " // Your initialization goes here" << endl << indent() << "}" << endl << endl; + f_skeleton << indent() << svcname << "Handler() {" << '\n' << indent() + << " // Your initialization goes here" << '\n' << indent() << "}" << '\n' << '\n'; vector functions = tservice->get_functions(); vector::iterator f_iter; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { generate_java_doc(f_skeleton, *f_iter); - f_skeleton << indent() << function_signature(*f_iter, "") << " {" << endl << indent() - << " // Your implementation goes here" << endl << indent() << " printf(\"" - << (*f_iter)->get_name() << "\\n\");" << endl << indent() << "}" << endl << endl; + f_skeleton << indent() << function_signature(*f_iter, "") << " {" << '\n' << indent() + << " // Your implementation goes here" << '\n' << indent() << " printf(\"" + << (*f_iter)->get_name() << "\\n\");" << '\n' << indent() << "}" << '\n' << '\n'; } indent_down(); - f_skeleton << "};" << endl << endl; + f_skeleton << "};" << '\n' << '\n'; - f_skeleton << indent() << "int main(int argc, char **argv) {" << endl; + f_skeleton << indent() << "int main(int argc, char **argv) {" << '\n'; indent_up(); f_skeleton - << indent() << "int port = 9090;" << endl << indent() << "::std::shared_ptr<" << svcname - << "Handler> handler(new " << svcname << "Handler());" << endl << indent() - << "::std::shared_ptr processor(new " << svcname << "Processor(handler));" << endl + << indent() << "int port = 9090;" << '\n' << indent() << "::std::shared_ptr<" << svcname + << "Handler> handler(new " << svcname << "Handler());" << '\n' << indent() + << "::std::shared_ptr processor(new " << svcname << "Processor(handler));" << '\n' << indent() << "::std::shared_ptr serverTransport(new TServerSocket(port));" - << endl << indent() - << "::std::shared_ptr transportFactory(new TBufferedTransportFactory());" << endl + << '\n' << indent() + << "::std::shared_ptr transportFactory(new TBufferedTransportFactory());" << '\n' << indent() << "::std::shared_ptr protocolFactory(new TBinaryProtocolFactory());" - << endl << endl << indent() + << '\n' << '\n' << indent() << "TSimpleServer server(processor, serverTransport, transportFactory, protocolFactory);" - << endl << indent() << "server.serve();" << endl << indent() << "return 0;" << endl; + << '\n' << indent() << "server.serve();" << '\n' << indent() << "return 0;" << '\n'; indent_down(); - f_skeleton << "}" << endl << endl; + f_skeleton << "}" << '\n' << '\n'; // Close the files f_skeleton.close(); @@ -3972,6 +4059,9 @@ void t_cpp_generator::generate_deserialize_field(ostream& out, case t_base_type::TYPE_VOID: throw "compiler error: cannot serialize void field in a struct: " + name; break; + case t_base_type::TYPE_UUID: + out << "readUUID(" << name << ");"; + break; case t_base_type::TYPE_STRING: if (type->is_binary()) { out << "readBinary(" << name << ");"; @@ -3998,14 +4088,14 @@ void t_cpp_generator::generate_deserialize_field(ostream& out, out << "readDouble(" << name << ");"; break; default: - throw "compiler error: no C++ reader for base type " + t_base_type::t_base_name(tbase) + name; + throw "compiler error: no C++ reader for base type " + t_base_type::t_base_name(tbase) + " " + name; } - out << endl; + out << '\n'; } else if (type->is_enum()) { string t = tmp("ecast"); - out << indent() << "int32_t " << t << ";" << endl << indent() << "xfer += iprot->readI32(" << t - << ");" << endl << indent() << name << " = static_cast<" - << type_name(type) << ">(" << t << ");" << endl; + out << indent() << "int32_t " << t << ";" << '\n' << indent() << "xfer += iprot->readI32(" << t + << ");" << '\n' << indent() << name << " = static_cast<" + << type_name(type) << ">(" << t << ");" << '\n'; } else { printf("DO NOT KNOW HOW TO DESERIALIZE FIELD '%s' TYPE '%s'\n", tfield->get_name().c_str(), @@ -4024,22 +4114,22 @@ void t_cpp_generator::generate_deserialize_struct(ostream& out, string prefix, bool pointer) { if (pointer) { - indent(out) << "if (!" << prefix << ") { " << endl; + indent(out) << "if (!" << prefix << ") { " << '\n'; indent(out) << " " << prefix << " = ::std::shared_ptr<" << type_name(tstruct) << ">(new " - << type_name(tstruct) << ");" << endl; - indent(out) << "}" << endl; - indent(out) << "xfer += " << prefix << "->read(iprot);" << endl; - indent(out) << "bool wasSet = false;" << endl; + << type_name(tstruct) << ");" << '\n'; + indent(out) << "}" << '\n'; + indent(out) << "xfer += " << prefix << "->read(iprot);" << '\n'; + indent(out) << "bool wasSet = false;" << '\n'; const vector& members = tstruct->get_members(); vector::const_iterator f_iter; for (f_iter = members.begin(); f_iter != members.end(); ++f_iter) { indent(out) << "if (" << prefix << "->__isset." << (*f_iter)->get_name() - << ") { wasSet = true; }" << endl; + << ") { wasSet = true; }" << '\n'; } - indent(out) << "if (!wasSet) { " << prefix << ".reset(); }" << endl; + indent(out) << "if (!wasSet) { " << prefix << ".reset(); }" << '\n'; } else { - indent(out) << "xfer += " << prefix << ".read(iprot);" << endl; + indent(out) << "xfer += " << prefix << ".read(iprot);" << '\n'; } } @@ -4054,28 +4144,28 @@ void t_cpp_generator::generate_deserialize_container(ostream& out, t_type* ttype t_container* tcontainer = (t_container*)ttype; bool use_push = tcontainer->has_cpp_name(); - indent(out) << prefix << ".clear();" << endl << indent() << "uint32_t " << size << ";" << endl; + indent(out) << prefix << ".clear();" << '\n' << indent() << "uint32_t " << size << ";" << '\n'; // Declare variables, read header if (ttype->is_map()) { - out << indent() << "::apache::thrift::protocol::TType " << ktype << ";" << endl << indent() - << "::apache::thrift::protocol::TType " << vtype << ";" << endl << indent() - << "xfer += iprot->readMapBegin(" << ktype << ", " << vtype << ", " << size << ");" << endl; + out << indent() << "::apache::thrift::protocol::TType " << ktype << ";" << '\n' << indent() + << "::apache::thrift::protocol::TType " << vtype << ";" << '\n' << indent() + << "xfer += iprot->readMapBegin(" << ktype << ", " << vtype << ", " << size << ");" << '\n'; } else if (ttype->is_set()) { - out << indent() << "::apache::thrift::protocol::TType " << etype << ";" << endl << indent() - << "xfer += iprot->readSetBegin(" << etype << ", " << size << ");" << endl; + out << indent() << "::apache::thrift::protocol::TType " << etype << ";" << '\n' << indent() + << "xfer += iprot->readSetBegin(" << etype << ", " << size << ");" << '\n'; } else if (ttype->is_list()) { - out << indent() << "::apache::thrift::protocol::TType " << etype << ";" << endl << indent() - << "xfer += iprot->readListBegin(" << etype << ", " << size << ");" << endl; + out << indent() << "::apache::thrift::protocol::TType " << etype << ";" << '\n' << indent() + << "xfer += iprot->readListBegin(" << etype << ", " << size << ");" << '\n'; if (!use_push) { - indent(out) << prefix << ".resize(" << size << ");" << endl; + indent(out) << prefix << ".resize(" << size << ");" << '\n'; } } // For loop iterates over elements string i = tmp("_i"); - out << indent() << "uint32_t " << i << ";" << endl << indent() << "for (" << i << " = 0; " << i - << " < " << size << "; ++" << i << ")" << endl; + out << indent() << "uint32_t " << i << ";" << '\n' << indent() << "for (" << i << " = 0; " << i + << " < " << size << "; ++" << i << ")" << '\n'; scope_up(out); @@ -4091,11 +4181,11 @@ void t_cpp_generator::generate_deserialize_container(ostream& out, t_type* ttype // Read container end if (ttype->is_map()) { - indent(out) << "xfer += iprot->readMapEnd();" << endl; + indent(out) << "xfer += iprot->readMapEnd();" << '\n'; } else if (ttype->is_set()) { - indent(out) << "xfer += iprot->readSetEnd();" << endl; + indent(out) << "xfer += iprot->readSetEnd();" << '\n'; } else if (ttype->is_list()) { - indent(out) << "xfer += iprot->readListEnd();" << endl; + indent(out) << "xfer += iprot->readListEnd();" << '\n'; } scope_down(out); @@ -4110,11 +4200,11 @@ void t_cpp_generator::generate_deserialize_map_element(ostream& out, t_map* tmap 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(&fkey) << '\n'; generate_deserialize_field(out, &fkey); indent(out) << declare_field(&fval, false, false, false, true) << " = " << prefix << "[" << key - << "];" << endl; + << "];" << '\n'; generate_deserialize_field(out, &fval); } @@ -4123,11 +4213,11 @@ void t_cpp_generator::generate_deserialize_set_element(ostream& out, t_set* tset string elem = tmp("_elem"); t_field felem(tset->get_elem_type(), elem); - indent(out) << declare_field(&felem) << endl; + indent(out) << declare_field(&felem) << '\n'; generate_deserialize_field(out, &felem); - indent(out) << prefix << ".insert(" << elem << ");" << endl; + indent(out) << prefix << ".insert(" << elem << ");" << '\n'; } void t_cpp_generator::generate_deserialize_list_element(ostream& out, @@ -4138,9 +4228,9 @@ void t_cpp_generator::generate_deserialize_list_element(ostream& out, if (use_push) { string elem = tmp("_elem"); t_field felem(tlist->get_elem_type(), elem); - indent(out) << declare_field(&felem) << endl; + indent(out) << declare_field(&felem) << '\n'; generate_deserialize_field(out, &felem); - indent(out) << prefix << ".push_back(" << elem << ");" << endl; + indent(out) << prefix << ".push_back(" << elem << ");" << '\n'; } else { t_field felem(tlist->get_elem_type(), prefix + "[" + index + "]"); generate_deserialize_field(out, &felem); @@ -4180,6 +4270,9 @@ void t_cpp_generator::generate_serialize_field(ostream& out, case t_base_type::TYPE_VOID: throw "compiler error: cannot serialize void field in a struct: " + name; break; + case t_base_type::TYPE_UUID: + out << "writeUUID(" << name << ");"; + break; case t_base_type::TYPE_STRING: if (type->is_binary()) { out << "writeBinary(" << name << ");"; @@ -4207,12 +4300,12 @@ void t_cpp_generator::generate_serialize_field(ostream& out, break; default: throw "compiler error: no C++ writer for base type " + t_base_type::t_base_name(tbase) - + name; + + " " + name; } } else if (type->is_enum()) { out << "writeI32(static_cast(" << name << "));"; } - out << endl; + out << '\n'; } else { printf("DO NOT KNOW HOW TO SERIALIZE FIELD '%s' TYPE '%s'\n", name.c_str(), @@ -4231,15 +4324,15 @@ void t_cpp_generator::generate_serialize_struct(ostream& out, string prefix, bool pointer) { if (pointer) { - indent(out) << "if (" << prefix << ") {" << endl; - indent(out) << " xfer += " << prefix << "->write(oprot); " << endl; + indent(out) << "if (" << prefix << ") {" << '\n'; + indent(out) << " xfer += " << prefix << "->write(oprot); " << '\n'; indent(out) << "} else {" - << "oprot->writeStructBegin(\"" << tstruct->get_name() << "\"); " << endl; - indent(out) << " oprot->writeStructEnd();" << endl; - indent(out) << " oprot->writeFieldStop();" << endl; - indent(out) << "}" << endl; + << "oprot->writeStructBegin(\"" << tstruct->get_name() << "\"); " << '\n'; + indent(out) << " oprot->writeStructEnd();" << '\n'; + indent(out) << " oprot->writeFieldStop();" << '\n'; + indent(out) << "}" << '\n'; } else { - indent(out) << "xfer += " << prefix << ".write(oprot);" << endl; + indent(out) << "xfer += " << prefix << ".write(oprot);" << '\n'; } } @@ -4249,21 +4342,21 @@ void t_cpp_generator::generate_serialize_container(ostream& out, t_type* ttype, if (ttype->is_map()) { indent(out) << "xfer += oprot->writeMapBegin(" << type_to_enum(((t_map*)ttype)->get_key_type()) << ", " << type_to_enum(((t_map*)ttype)->get_val_type()) << ", " - << "static_cast(" << prefix << ".size()));" << endl; + << "static_cast(" << prefix << ".size()));" << '\n'; } else if (ttype->is_set()) { indent(out) << "xfer += oprot->writeSetBegin(" << type_to_enum(((t_set*)ttype)->get_elem_type()) << ", " - << "static_cast(" << prefix << ".size()));" << endl; + << "static_cast(" << prefix << ".size()));" << '\n'; } else if (ttype->is_list()) { indent(out) << "xfer += oprot->writeListBegin(" << type_to_enum(((t_list*)ttype)->get_elem_type()) << ", " - << "static_cast(" << prefix << ".size()));" << endl; + << "static_cast(" << prefix << ".size()));" << '\n'; } string iter = tmp("_iter"); - out << indent() << type_name(ttype) << "::const_iterator " << iter << ";" << endl << indent() + out << indent() << type_name(ttype) << "::const_iterator " << iter << ";" << '\n' << indent() << "for (" << iter << " = " << prefix << ".begin(); " << iter << " != " << prefix - << ".end(); ++" << iter << ")" << endl; + << ".end(); ++" << iter << ")" << '\n'; scope_up(out); if (ttype->is_map()) { generate_serialize_map_element(out, (t_map*)ttype, iter); @@ -4275,11 +4368,11 @@ void t_cpp_generator::generate_serialize_container(ostream& out, t_type* ttype, scope_down(out); if (ttype->is_map()) { - indent(out) << "xfer += oprot->writeMapEnd();" << endl; + indent(out) << "xfer += oprot->writeMapEnd();" << '\n'; } else if (ttype->is_set()) { - indent(out) << "xfer += oprot->writeSetEnd();" << endl; + indent(out) << "xfer += oprot->writeSetEnd();" << '\n'; } else if (ttype->is_list()) { - indent(out) << "xfer += oprot->writeListEnd();" << endl; + indent(out) << "xfer += oprot->writeListEnd();" << '\n'; } scope_down(out); @@ -4408,7 +4501,7 @@ string t_cpp_generator::type_name(t_type* ttype, bool in_typedef, bool arg) { return bname; } - if (((t_base_type*)ttype)->get_base() == t_base_type::TYPE_STRING) { + if ((((t_base_type*)ttype)->get_base() == t_base_type::TYPE_STRING) || ((((t_base_type*)ttype)->get_base() == t_base_type::TYPE_UUID))) { return "const " + bname + "&"; } else { return "const " + bname; @@ -4494,6 +4587,8 @@ string t_cpp_generator::base_type_name(t_base_type::t_base tbase) { return "int64_t"; case t_base_type::TYPE_DOUBLE: return "double"; + case t_base_type::TYPE_UUID: + return "apache::thrift::TUuid"; default: throw "compiler error: no C++ base type name for base type " + t_base_type::t_base_name(tbase); } @@ -4528,30 +4623,35 @@ string t_cpp_generator::declare_field(t_field* tfield, result += " " + tfield->get_name(); if (init) { t_type* type = get_true_type(tfield->get_type()); + if (t_const_value* cv = tfield->get_value()) { + result += " = " + render_const_value(nullptr, tfield->get_name(), type, cv); + } else { + if (type->is_base_type()) { + t_base_type::t_base tbase = ((t_base_type*)type)->get_base(); - 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: - case t_base_type::TYPE_STRING: - 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 += " = 0.0"; - break; - default: - throw "compiler error: no C++ initializer for base type " + t_base_type::t_base_name(tbase); + switch (tbase) { + case t_base_type::TYPE_VOID: + case t_base_type::TYPE_STRING: + case t_base_type::TYPE_UUID: + 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 += " = 0.0"; + break; + default: + throw "compiler error: no C++ initializer for base type " + t_base_type::t_base_name(tbase); + } + } else if (type->is_enum()) { + result += " = static_cast<" + type_name(type) + ">(0)"; } - } else if (type->is_enum()) { - result += " = static_cast<" + type_name(type) + ">(0)"; } } if (!reference) { @@ -4661,6 +4761,8 @@ string t_cpp_generator::type_to_enum(t_type* type) { return "::apache::thrift::protocol::T_I64"; case t_base_type::TYPE_DOUBLE: return "::apache::thrift::protocol::T_DOUBLE"; + case t_base_type::TYPE_UUID: + return "::apache::thrift::protocol::T_UUID"; default: break; } @@ -4699,6 +4801,7 @@ bool t_cpp_generator::is_struct_storage_not_throwing(t_struct* tstruct) const { case t_base_type::TYPE_I32: case t_base_type::TYPE_I64: case t_base_type::TYPE_DOUBLE: + case t_base_type::TYPE_UUID: continue; case t_base_type::TYPE_VOID: case t_base_type::TYPE_STRING: diff --git a/compiler/cpp/src/thrift/generate/t_d_generator.cc b/compiler/cpp/src/thrift/generate/t_d_generator.cc index 38194c20719..61988dfc491 100644 --- a/compiler/cpp/src/thrift/generate/t_d_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_d_generator.cc @@ -43,8 +43,6 @@ using std::set; using std::string; using std::vector; -static const string endl = "\n"; // avoid ostream << std::endl flushes - /** * D code generator. * @@ -105,7 +103,7 @@ class t_d_generator : public t_oop_generator { // Print header f_types_ << autogen_comment() << "module " << render_package(*program_) << program_name_ - << "_types;" << endl << endl; + << "_types;" << '\n' << '\n'; print_default_imports(f_types_); @@ -113,10 +111,10 @@ class t_d_generator : public t_oop_generator { const vector& includes = program_->get_includes(); for (auto include : includes) { f_types_ << "public import " << render_package(*include) << include->get_name() - << "_types;" << endl; + << "_types;" << '\n'; } if (!includes.empty()) - f_types_ << endl; + f_types_ << '\n'; } void close_generator() override { @@ -131,22 +129,22 @@ class t_d_generator : public t_oop_generator { f_consts.open(f_consts_name.c_str()); f_consts << autogen_comment() << "module " << render_package(*program_) << program_name_ - << "_constants;" << endl << endl; + << "_constants;" << '\n' << '\n'; print_default_imports(f_consts); - f_consts << "import " << render_package(*get_program()) << program_name_ << "_types;" << endl - << endl; + f_consts << "import " << render_package(*get_program()) << program_name_ << "_types;" << '\n' + << '\n'; vector::iterator c_iter; for (c_iter = consts.begin(); c_iter != consts.end(); ++c_iter) { this->emit_doc(*c_iter, f_consts); string name = suffix_if_reserved((*c_iter)->get_name()); t_type* type = (*c_iter)->get_type(); - indent(f_consts) << "immutable(" << render_type_name(type) << ") " << name << ";" << endl; + indent(f_consts) << "immutable(" << render_type_name(type) << ") " << name << ";" << '\n'; } - f_consts << endl << "shared static this() {" << endl; + f_consts << '\n' << "shared static this() {" << '\n'; indent_up(); bool first = true; @@ -154,24 +152,24 @@ class t_d_generator : public t_oop_generator { if (first) { first = false; } else { - f_consts << endl; + f_consts << '\n'; } t_type* type = (*c_iter)->get_type(); indent(f_consts) << suffix_if_reserved((*c_iter)->get_name()) << " = "; if (!is_immutable_type(type)) { f_consts << "cast(immutable(" << render_type_name(type) << ")) "; } - f_consts << render_const_value(type, (*c_iter)->get_value()) << ";" << endl; + f_consts << render_const_value(type, (*c_iter)->get_value()) << ";" << '\n'; } indent_down(); - indent(f_consts) << "}" << endl; + indent(f_consts) << "}" << '\n'; } } 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; + << ttypedef->get_symbolic() << ";" << '\n' << '\n'; } void generate_enum(t_enum* tenum) override { @@ -179,7 +177,7 @@ class t_d_generator : public t_oop_generator { this->emit_doc(tenum, f_types_); string enum_name = suffix_if_reserved(tenum->get_name()); - f_types_ << indent() << "enum " << enum_name << " {" << endl; + f_types_ << indent() << "enum " << enum_name << " {" << '\n'; indent_up(); @@ -190,11 +188,11 @@ class t_d_generator : public t_oop_generator { f_types_ << " = " << (*c_iter)->get_value() << ","; } - f_types_ << endl; + f_types_ << '\n'; indent_down(); - indent(f_types_) << "}" << endl; + indent(f_types_) << "}" << '\n'; - f_types_ << endl; + f_types_ << '\n'; } void generate_struct(t_struct* tstruct) override { @@ -213,19 +211,19 @@ class t_d_generator : public t_oop_generator { ofstream_with_content_based_conditional_update f_service; f_service.open(f_servicename.c_str()); f_service << autogen_comment() << "module " << suffix_if_reserved(render_package(*program_)) << svc_name << ";" - << endl << endl; + << '\n' << '\n'; print_default_imports(f_service); - f_service << "import " << suffix_if_reserved(render_package(*get_program())) << program_name_ << "_types;" << endl; + f_service << "import " << suffix_if_reserved(render_package(*get_program())) << program_name_ << "_types;" << '\n'; t_service* extends_service = tservice->get_extends(); if (extends_service != nullptr) { f_service << "import " << suffix_if_reserved(render_package(*(extends_service->get_program()))) - << suffix_if_reserved(extends_service->get_name()) << ";" << endl; + << suffix_if_reserved(extends_service->get_name()) << ";" << '\n'; } - f_service << endl; + f_service << '\n'; string extends = ""; if (tservice->get_extends() != nullptr) { @@ -233,7 +231,7 @@ class t_d_generator : public t_oop_generator { } this->emit_doc(tservice, f_service); - f_service << indent() << "interface " << svc_name << extends << " {" << endl; + f_service << indent() << "interface " << svc_name << extends << " {" << '\n'; indent_up(); // Collect all the exception types service methods can throw so we can @@ -247,7 +245,7 @@ class t_d_generator : public t_oop_generator { this->emit_doc(*fn_iter, f_service); f_service << indent(); print_function_signature(f_service, *fn_iter); - f_service << ";" << endl; + f_service << ";" << '\n'; const vector& exceptions = (*fn_iter)->get_xceptions()->get_members(); vector::const_iterator ex_iter; @@ -258,13 +256,13 @@ class t_d_generator : public t_oop_generator { // Alias the exception types into the current scope. if (!exception_types.empty()) - f_service << endl; + f_service << '\n'; set::const_iterator et_iter; for (et_iter = exception_types.begin(); et_iter != exception_types.end(); ++et_iter) { indent(f_service) << "alias " << render_package(*(*et_iter)->get_program()) << (*et_iter)->get_program()->get_name() << "_types" << "." << (*et_iter)->get_name() << " " << (*et_iter)->get_name() << ";" - << endl; + << '\n'; } // Write the method metadata. @@ -283,7 +281,7 @@ class t_d_generator : public t_oop_generator { meta << ","; } - meta << endl << indent() << "TMethodMeta(`" << suffix_if_reserved((*fn_iter)->get_name()) << "`, " << endl; + meta << '\n' << indent() << "TMethodMeta(`" << suffix_if_reserved((*fn_iter)->get_name()) << "`, " << '\n'; indent_up(); indent(meta) << "["; @@ -309,7 +307,7 @@ class t_d_generator : public t_oop_generator { meta << "]"; if (!(*fn_iter)->get_xceptions()->get_members().empty() || (*fn_iter)->is_oneway()) { - meta << "," << endl << indent() << "["; + meta << "," << '\n' << indent() << "["; bool first = true; const vector& exceptions = (*fn_iter)->get_xceptions()->get_members(); @@ -329,22 +327,22 @@ class t_d_generator : public t_oop_generator { } if ((*fn_iter)->is_oneway()) { - meta << "," << endl << indent() << "TMethodType.ONEWAY"; + meta << "," << '\n' << indent() << "TMethodType.ONEWAY"; } indent_down(); - meta << endl << indent() << ")"; + meta << '\n' << indent() << ")"; } indent_down(); string meta_str(meta.str()); if (!meta_str.empty()) { - f_service << endl << indent() << "enum methodMeta = [" << meta_str << endl << indent() << "];" - << endl; + f_service << '\n' << indent() << "enum methodMeta = [" << meta_str << '\n' << indent() << "];" + << '\n'; } indent_down(); - indent(f_service) << "}" << endl; + indent(f_service) << "}" << '\n'; // Server skeleton generation. string f_skeletonname = package_dir_ + svc_name + "_server.skeleton.d"; @@ -358,14 +356,14 @@ class t_d_generator : public t_oop_generator { if (!doc->has_doc()) { return; } - indent(out) << "/**" << std::endl; + indent(out) << "/**" << '\n'; indent_up(); - // No endl -- comments reliably have a newline at the end. + // No line break -- comments reliably have a newline at the end. // This is true even for stuff like: // /** method infos */ void foo(/** huh?*/ 1: i64 stuff) indent(out) << doc->get_doc(); indent_down(); - indent(out) << "*/" << std::endl; + indent(out) << "*/" << '\n'; } private: @@ -376,59 +374,59 @@ class t_d_generator : public t_oop_generator { void print_server_skeleton(ostream& out, t_service* tservice) { string svc_name = suffix_if_reserved(tservice->get_name()); - out << "/*" << endl - << " * This auto-generated skeleton file illustrates how to build a server. If you" << endl - << " * intend to customize it, you should edit a copy with another file name to " << endl - << " * avoid overwriting it when running the generator again." << endl << " */" << endl - << "module " << render_package(*tservice->get_program()) << svc_name << "_server;" << endl - << endl << "import std.stdio;" << endl << "import thrift.codegen.processor;" << endl - << "import thrift.protocol.binary;" << endl << "import thrift.server.simple;" << endl - << "import thrift.server.transport.socket;" << endl << "import thrift.transport.buffered;" - << endl << "import thrift.util.hashset;" << endl << endl << "import " - << render_package(*tservice->get_program()) << svc_name << ";" << endl << "import " - << render_package(*get_program()) << program_name_ << "_types;" << endl << endl << endl - << "class " << svc_name << "Handler : " << svc_name << " {" << endl; + out << "/*" << '\n' + << " * This auto-generated skeleton file illustrates how to build a server. If you" << '\n' + << " * intend to customize it, you should edit a copy with another file name to " << '\n' + << " * avoid overwriting it when running the generator again." << '\n' << " */" << '\n' + << "module " << render_package(*tservice->get_program()) << svc_name << "_server;" << '\n' + << '\n' << "import std.stdio;" << '\n' << "import thrift.codegen.processor;" << '\n' + << "import thrift.protocol.binary;" << '\n' << "import thrift.server.simple;" << '\n' + << "import thrift.server.transport.socket;" << '\n' << "import thrift.transport.buffered;" + << '\n' << "import thrift.util.hashset;" << '\n' << '\n' << "import " + << render_package(*tservice->get_program()) << svc_name << ";" << '\n' << "import " + << render_package(*get_program()) << program_name_ << "_types;" << '\n' << '\n' << '\n' + << "class " << svc_name << "Handler : " << svc_name << " {" << '\n'; indent_up(); - out << indent() << "this() {" << endl << indent() << " // Your initialization goes here." - << endl << indent() << "}" << endl << endl; + out << indent() << "this() {" << '\n' << indent() << " // Your initialization goes here." + << '\n' << indent() << "}" << '\n' << '\n'; vector functions = tservice->get_functions(); vector::iterator f_iter; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { out << indent(); print_function_signature(out, *f_iter); - out << " {" << endl; + out << " {" << '\n'; indent_up(); - out << indent() << "// Your implementation goes here." << endl << indent() << "writeln(\"" - << suffix_if_reserved((*f_iter)->get_name()) << " called\");" << endl; + out << indent() << "// Your implementation goes here." << '\n' << indent() << "writeln(\"" + << suffix_if_reserved((*f_iter)->get_name()) << " called\");" << '\n'; t_type* rt = (*f_iter)->get_returntype(); if (!rt->is_void()) { - indent(out) << "return typeof(return).init;" << endl; + indent(out) << "return typeof(return).init;" << '\n'; } indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } indent_down(); - out << "}" << endl << endl; + out << "}" << '\n' << '\n'; - out << indent() << "void main() {" << endl; + out << indent() << "void main() {" << '\n'; indent_up(); - out << indent() << "auto protocolFactory = new TBinaryProtocolFactory!();" << endl << indent() + out << indent() << "auto protocolFactory = new TBinaryProtocolFactory!();" << '\n' << indent() << "auto processor = new TServiceProcessor!" << svc_name << "(new " << svc_name - << "Handler);" << endl << indent() << "auto serverTransport = new TServerSocket(9090);" - << endl << indent() << "auto transportFactory = new TBufferedTransportFactory;" << endl - << indent() << "auto server = new TSimpleServer(" << endl << indent() - << " processor, serverTransport, transportFactory, protocolFactory);" << endl << indent() - << "server.serve();" << endl; + << "Handler);" << '\n' << indent() << "auto serverTransport = new TServerSocket(9090);" + << '\n' << indent() << "auto transportFactory = new TBufferedTransportFactory;" << '\n' + << indent() << "auto server = new TSimpleServer(" << '\n' << indent() + << " processor, serverTransport, transportFactory, protocolFactory);" << '\n' << indent() + << "server.serve();" << '\n'; indent_down(); - out << "}" << endl; + out << "}" << '\n'; } /** @@ -439,9 +437,9 @@ class t_d_generator : public t_oop_generator { const vector& members = tstruct->get_members(); if (is_exception) { - indent(out) << "class " << suffix_if_reserved(tstruct->get_name()) << " : TException {" << endl; + indent(out) << "class " << suffix_if_reserved(tstruct->get_name()) << " : TException {" << '\n'; } else { - indent(out) << "struct " << suffix_if_reserved(tstruct->get_name()) << " {" << endl; + indent(out) << "struct " << suffix_if_reserved(tstruct->get_name()) << " {" << '\n'; } indent_up(); @@ -449,11 +447,11 @@ class t_d_generator : public t_oop_generator { vector::const_iterator m_iter; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { indent(out) << render_type_name((*m_iter)->get_type()) << " " << suffix_if_reserved((*m_iter)->get_name()) << ";" - << endl; + << '\n'; } if (!members.empty()) - indent(out) << endl; + indent(out) << '\n'; indent(out) << "mixin TStructHelpers!("; if (!members.empty()) { @@ -471,7 +469,7 @@ class t_d_generator : public t_oop_generator { } else { out << ","; } - out << endl; + out << '\n'; indent(out) << "TFieldMeta(`" << suffix_if_reserved((*m_iter)->get_name()) << "`, " << (*m_iter)->get_key(); @@ -485,13 +483,13 @@ class t_d_generator : public t_oop_generator { } indent_down(); - out << endl << indent() << "]"; + out << '\n' << indent() << "]"; } - out << ");" << endl; + out << ");" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } /** @@ -559,13 +557,13 @@ class t_d_generator : public t_oop_generator { } else if (type->is_enum()) { out << "cast(" << render_type_name(type) << ")" << value->get_integer(); } else { - out << "{" << endl; + out << "{" << '\n'; indent_up(); - indent(out) << render_type_name(type) << " v;" << endl; + indent(out) << render_type_name(type) << " v;" << '\n'; if (type->is_struct() || type->is_xception()) { indent(out) << "v = " << (type->is_xception() ? "new " : "") << render_type_name(type) - << "();" << endl; + << "();" << '\n'; const vector& fields = ((t_struct*)type)->get_members(); vector::const_iterator f_iter; @@ -583,7 +581,7 @@ class t_d_generator : public t_oop_generator { + v_iter->first->get_string(); } string val = render_const_value(field_type, v_iter->second); - indent(out) << "v.set!`" << v_iter->first->get_string() << "`(" << val << ");" << endl; + indent(out) << "v.set!`" << v_iter->first->get_string() << "`(" << val << ");" << '\n'; } } else if (type->is_map()) { t_type* ktype = ((t_map*)type)->get_key_type(); @@ -597,7 +595,7 @@ class t_d_generator : public t_oop_generator { if (!is_immutable_type(ktype)) { out << "cast(immutable(" << render_type_name(ktype) << "))"; } - out << key << "] = " << val << ";" << endl; + out << key << "] = " << val << ";" << '\n'; } } else if (type->is_list()) { t_type* etype = ((t_list*)type)->get_elem_type(); @@ -605,7 +603,7 @@ class t_d_generator : public t_oop_generator { vector::const_iterator v_iter; for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { string val = render_const_value(etype, *v_iter); - indent(out) << "v ~= " << val << ";" << endl; + indent(out) << "v ~= " << val << ";" << '\n'; } } else if (type->is_set()) { t_type* etype = ((t_set*)type)->get_elem_type(); @@ -613,12 +611,12 @@ class t_d_generator : public t_oop_generator { vector::const_iterator v_iter; for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { string val = render_const_value(etype, *v_iter); - indent(out) << "v ~= " << val << ";" << endl; + indent(out) << "v ~= " << val << ";" << '\n'; } } else { throw "Compiler error: Invalid type in render_const_value: " + type->get_name(); } - indent(out) << "return v;" << endl; + indent(out) << "return v;" << '\n'; indent_down(); indent(out) << "}()"; @@ -728,8 +726,8 @@ class t_d_generator : public t_oop_generator { */ void print_default_imports(ostream& out) { - indent(out) << "import thrift.base;" << endl << "import thrift.codegen.base;" << endl - << "import thrift.util.hashset;" << endl << endl; + indent(out) << "import thrift.base;" << '\n' << "import thrift.codegen.base;" << '\n' + << "import thrift.util.hashset;" << '\n' << '\n'; } /** diff --git a/compiler/cpp/src/thrift/generate/t_dart_generator.cc b/compiler/cpp/src/thrift/generate/t_dart_generator.cc index fda989b24c6..00550438ed2 100644 --- a/compiler/cpp/src/thrift/generate/t_dart_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_dart_generator.cc @@ -37,9 +37,6 @@ using std::string; using std::stringstream; using std::vector; -static const string endl = "\n"; // avoid ostream << std::endl flushes -static const string endl2 = "\n\n"; - /** * Use the current Thrift version for static libraries. When releasing, update * the version in these files. @@ -89,11 +86,11 @@ class t_dart_generator : public t_oop_generator { } void scope_up(std::ostream& out, std::string prefix=" ") { - out << prefix << "{" << endl; + out << prefix << "{" << '\n'; indent_up(); } - void scope_down(std::ostream& out, std::string postfix=endl) { + void scope_down(std::ostream& out, std::string postfix="\n") { indent_down(); indent(out) << "}" << postfix; } @@ -339,7 +336,7 @@ string t_dart_generator::dart_library(string file_name) { * @return List of imports for services */ string t_dart_generator::service_imports() { - return "import 'dart:async';" + endl; + return string("import 'dart:async';") + "\n"; } /** @@ -348,14 +345,14 @@ string t_dart_generator::service_imports() { * @return List of imports necessary for thrift */ string t_dart_generator::dart_thrift_imports() { - string imports = "import 'dart:typed_data' show Uint8List;" + endl + - "import 'package:thrift/thrift.dart';" + endl; + string imports = string("import 'dart:typed_data' show Uint8List;") + "\n" + + string("import 'package:thrift/thrift.dart';") + "\n"; // add import for this library if (package_prefix_.empty()) { - imports += "import 'package:" + library_name_ + "/" + library_name_ + ".dart';" + endl; + imports += "import 'package:" + library_name_ + "/" + library_name_ + ".dart';" + "\n"; } else { - imports += "import 'package:" + package_prefix_ + library_name_ + ".dart';" + endl; + imports += "import 'package:" + package_prefix_ + library_name_ + ".dart';" + "\n"; } // add imports for included thrift files @@ -364,9 +361,9 @@ string t_dart_generator::dart_thrift_imports() { 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; + imports += "import 'package:" + include_name + "/" + include_name + ".dart' as " + named_import + ";" + "\n"; } else { - imports += "import 'package:" + package_prefix_ + include_name + ".dart' as " + named_import + ";" + endl; + imports += "import 'package:" + package_prefix_ + include_name + ".dart' as " + named_import + ";" + "\n"; } } @@ -395,8 +392,8 @@ void t_dart_generator::generate_dart_library() { ofstream_with_content_based_conditional_update f_library; f_library.open(f_library_name.c_str()); - f_library << autogen_comment() << endl; - f_library << "library " << library_prefix_ << library_name_ << ";" << endl2; + f_library << autogen_comment() << '\n'; + f_library << "library " << library_prefix_ << library_name_ << ";" << '\n' << '\n'; f_library << library_exports_; f_library.close(); @@ -409,7 +406,7 @@ void t_dart_generator::export_class_to_library(string file_name, string class_na } else { subdir = library_name_; } - library_exports_ += "export '" + subdir + "/" + file_name + ".dart' show " + class_name + ";" + endl; + library_exports_ += "export '" + subdir + "/" + file_name + ".dart' show " + class_name + ";" + "\n"; } void t_dart_generator::generate_dart_pubspec() { @@ -417,30 +414,30 @@ void t_dart_generator::generate_dart_pubspec() { ofstream_with_content_based_conditional_update f_pubspec; f_pubspec.open(f_pubspec_name.c_str()); - indent(f_pubspec) << "name: " << library_name_ << endl; - indent(f_pubspec) << "version: 0.0.1" << endl; - indent(f_pubspec) << "description: Autogenerated by Thrift Compiler" << endl; - f_pubspec << endl; + indent(f_pubspec) << "name: " << library_name_ << '\n'; + indent(f_pubspec) << "version: 0.0.1" << '\n'; + indent(f_pubspec) << "description: Autogenerated by Thrift Compiler" << '\n'; + f_pubspec << '\n'; - indent(f_pubspec) << "environment:" << endl; + indent(f_pubspec) << "environment:" << '\n'; indent_up(); - indent(f_pubspec) << "sdk: '>=1.24.3 <3.0.0'" << endl; + indent(f_pubspec) << "sdk: '>=1.24.3 <3.0.0'" << '\n'; indent_down(); - f_pubspec << endl; + f_pubspec << '\n'; - indent(f_pubspec) << "dependencies:" << endl; + indent(f_pubspec) << "dependencies:" << '\n'; indent_up(); if (pubspec_lib_.empty()) { // default to relative path within working directory, which works for tests - indent(f_pubspec) << "thrift: # ^" << dart_thrift_version << endl; + indent(f_pubspec) << "thrift: # ^" << dart_thrift_version << '\n'; indent_up(); - indent(f_pubspec) << "path: ../../../../lib/dart" << endl; + indent(f_pubspec) << "path: ../../../../lib/dart" << '\n'; indent_down(); } else { const vector lines = split(pubspec_lib_, '|'); for (const auto & line : lines) { - indent(f_pubspec) << line << endl; + indent(f_pubspec) << line << '\n'; } } @@ -448,14 +445,14 @@ void t_dart_generator::generate_dart_pubspec() { const vector& includes = program_->get_includes(); for (auto include : includes) { string include_name = find_library_name(include); - indent(f_pubspec) << include_name << ":" << endl; + indent(f_pubspec) << include_name << ":" << '\n'; indent_up(); - indent(f_pubspec) << "path: ../" << include_name << endl; + indent(f_pubspec) << "path: ../" << include_name << '\n'; indent_down(); } indent_down(); - f_pubspec << endl; + f_pubspec << '\n'; f_pubspec.close(); } @@ -483,7 +480,7 @@ void t_dart_generator::generate_enum(t_enum* tenum) { f_enum.open(f_enum_name.c_str()); // Comment and add library - f_enum << autogen_comment() << dart_library(file_name) << endl; + f_enum << autogen_comment() << dart_library(file_name) << '\n'; string class_name = tenum->get_name(); export_class_to_library(file_name, class_name); @@ -495,34 +492,34 @@ void t_dart_generator::generate_enum(t_enum* tenum) { for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) { int value = (*c_iter)->get_value(); indent(f_enum) << "static const int " << (*c_iter)->get_name() << " = " << value << ";" - << endl; + << '\n'; } // Create a static Set with all valid values for this enum - f_enum << endl; + f_enum << '\n'; - indent(f_enum) << "static final Set VALID_VALUES = new Set.from([" << endl; + indent(f_enum) << "static final Set VALID_VALUES = new Set.from([" << '\n'; indent_up(); bool firstValue = true; for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) { // populate set indent(f_enum) << (firstValue ? "" : ", "); - f_enum << (*c_iter)->get_name() << endl; + f_enum << (*c_iter)->get_name() << '\n'; firstValue = false; } indent_down(); - indent(f_enum) << "]);" << endl; + indent(f_enum) << "]);" << '\n'; - indent(f_enum) << "static final Map VALUES_TO_NAMES = {" << endl; + indent(f_enum) << "static final Map VALUES_TO_NAMES = {" << '\n'; indent_up(); firstValue = true; for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) { indent(f_enum) << (firstValue ? "" : ", "); - f_enum << (*c_iter)->get_name() << ": '" << (*c_iter)->get_name() << "'" << endl; + f_enum << (*c_iter)->get_name() << ": '" << (*c_iter)->get_name() << "'" << '\n'; firstValue = false; } indent_down(); - indent(f_enum) << "};" << endl; + indent(f_enum) << "};" << '\n'; scope_down(f_enum); // end class @@ -545,8 +542,8 @@ void t_dart_generator::generate_consts(std::vector consts) { f_consts.open(f_consts_name.c_str()); // Print header - f_consts << autogen_comment() << dart_library(file_name) << endl; - f_consts << dart_thrift_imports() << endl; + f_consts << autogen_comment() << dart_library(file_name) << '\n'; + f_consts << dart_thrift_imports() << '\n'; export_class_to_library(file_name, class_name); indent(f_consts) << "class " << class_name; @@ -559,7 +556,7 @@ void t_dart_generator::generate_consts(std::vector consts) { (*c_iter)->get_type(), (*c_iter)->get_value(), false); - f_consts << endl; + f_consts << '\n'; } scope_down(f_consts); @@ -585,13 +582,13 @@ void t_dart_generator::print_const_value(std::ostream& out, } string v2 = render_const_value(out, name, type, value); out << name; - out << " = " << v2 << ";" << endl << endl; + out << " = " << v2 << ";" << '\n' << '\n'; } else if (type->is_enum()) { if (!defval) { out << type_name(type) << " "; } out << name; - out << " = " << value->get_integer() << ";" << endl << endl; + out << " = " << value->get_integer() << ";" << '\n' << '\n'; } else if (type->is_struct() || type->is_xception()) { const vector& fields = ((t_struct*)type)->get_members(); vector::const_iterator f_iter; @@ -610,11 +607,11 @@ void t_dart_generator::print_const_value(std::ostream& out, throw "type error: " + type->get_name() + " has no field " + v_iter->first->get_string(); } string val = render_const_value(out, name, field_type, v_iter->second); - out << endl; + out << '\n'; indent(out) << ".." << v_iter->first->get_string() << " = " << val; } indent_down(); - out << ";" << endl; + out << ";" << '\n'; } else if (type->is_map()) { if (!defval) { out << type_name(type) << " "; @@ -630,11 +627,11 @@ void t_dart_generator::print_const_value(std::ostream& out, 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); - indent(out) << key << ": " << val << "," << endl; + indent(out) << key << ": " << val << "," << '\n'; } - scope_down(out, ";" + endl); + scope_down(out, string(";") + "\n"); - out << endl; + out << '\n'; } else if (type->is_list() || type->is_set()) { if (!defval) { out << type_name(type) << " "; @@ -642,10 +639,10 @@ void t_dart_generator::print_const_value(std::ostream& out, out << name << " = "; t_type* etype; if (type->is_list()) { - out << "[" << endl; + out << "[" << '\n'; etype = ((t_list*)type)->get_elem_type(); } else { - out << "new " << type_name(type) << ".from([" << endl; + out << "new " << type_name(type) << ".from([" << '\n'; etype = ((t_set*)type)->get_elem_type(); } const vector& val = value->get_list(); @@ -654,14 +651,14 @@ void t_dart_generator::print_const_value(std::ostream& out, indent_up(); for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { string val = render_const_value(out, name, etype, *v_iter); - indent(out) << val << "," << endl; + indent(out) << val << "," << '\n'; } indent_down(); if (type->is_list()) { - indent(out) << "];" << endl; + indent(out) << "];" << '\n'; } else { - indent(out) << "]);" << endl; + indent(out) << "]);" << '\n'; } } else { @@ -707,7 +704,7 @@ string t_dart_generator::render_const_value(ostream& out, } else { string t = tmp("tmp"); print_const_value(out, t, type, value, true); - out << endl; + out << '\n'; render << t; } @@ -744,11 +741,11 @@ void t_dart_generator::generate_dart_struct(t_struct* tstruct, bool is_exception ofstream_with_content_based_conditional_update f_struct; f_struct.open(f_struct_name.c_str()); - f_struct << autogen_comment() << dart_library(file_name) << endl; + f_struct << autogen_comment() << dart_library(file_name) << '\n'; string imports; - f_struct << dart_thrift_imports() << endl; + f_struct << dart_thrift_imports() << '\n'; generate_dart_struct_definition(f_struct, tstruct, is_exception, false, file_name); @@ -785,7 +782,7 @@ void t_dart_generator::generate_dart_struct_definition(ostream& out, scope_up(out); indent(out) << "static final TStruct _STRUCT_DESC = new TStruct(\"" << class_name - << "\");" << endl; + << "\");" << '\n'; // Members are public for -dart, private for -dartbean const vector& members = tstruct->get_members(); @@ -795,33 +792,33 @@ void t_dart_generator::generate_dart_struct_definition(ostream& out, indent(out) << "static final TField _" << constant_name((*m_iter)->get_name()) << "_FIELD_DESC = new TField(\"" << (*m_iter)->get_name() << "\", " << type_to_enum((*m_iter)->get_type()) << ", " << (*m_iter)->get_key() << ");" - << endl; + << '\n'; } - out << endl; + out << '\n'; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { generate_dart_doc(out, *m_iter); indent(out) << type_name((*m_iter)->get_type()) + " _" - << get_member_name((*m_iter)->get_name()) << init_value(*m_iter) << ";" << endl; + << get_member_name((*m_iter)->get_name()) << init_value(*m_iter) << ";" << '\n'; indent(out) << "static const int " << upcase_string((*m_iter)->get_name()) - << " = " << (*m_iter)->get_key() << ";" << endl; + << " = " << (*m_iter)->get_key() << ";" << '\n'; } - out << endl; + out << '\n'; // Inner Isset class if (members.size() > 0) { for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { if (!type_can_be_null((*m_iter)->get_type())) { string field_name = get_member_name((*m_iter)->get_name()); - indent(out) << "bool __isset_" << field_name << " = false;" << endl; + indent(out) << "bool __isset_" << field_name << " = false;" << '\n'; } } } - out << endl; + out << '\n'; // Default constructor indent(out) << tstruct->get_name() << "()"; @@ -838,7 +835,7 @@ void t_dart_generator::generate_dart_struct_definition(ostream& out, } } scope_down(out); - out << endl; + out << '\n'; generate_dart_bean_boilerplate(out, tstruct); generate_generic_field_getters(out, tstruct); @@ -854,7 +851,7 @@ void t_dart_generator::generate_dart_struct_definition(ostream& out, generate_dart_struct_tostring(out, tstruct); generate_dart_validator(out, tstruct); scope_down(out); - out << endl; + out << '\n'; } /** @@ -870,20 +867,20 @@ void t_dart_generator::generate_dart_struct_reader(ostream& out, t_struct* tstru vector::const_iterator f_iter; // Declare stack tmp variables and read struct header - indent(out) << "TField field;" << endl; - indent(out) << "iprot.readStructBegin();" << endl; + indent(out) << "TField field;" << '\n'; + indent(out) << "iprot.readStructBegin();" << '\n'; // Loop over reading in fields indent(out) << "while (true)"; scope_up(out); // Read beginning field marker - indent(out) << "field = iprot.readFieldBegin();" << endl; + indent(out) << "field = iprot.readFieldBegin();" << '\n'; // Check for field STOP marker and break indent(out) << "if (field.type == TType.STOP)"; scope_up(out); - indent(out) << "break;" << endl; + indent(out) << "break;" << '\n'; scope_down(out); // Switch statement on the field we are reading @@ -892,7 +889,7 @@ void t_dart_generator::generate_dart_struct_reader(ostream& out, t_struct* tstru // Generate deserialization code for known cases for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { - indent(out) << "case " << upcase_string((*f_iter)->get_name()) << ":" << endl; + indent(out) << "case " << upcase_string((*f_iter)->get_name()) << ":" << '\n'; indent_up(); indent(out) << "if (field.type == " << type_to_enum((*f_iter)->get_type()) << ")"; @@ -903,33 +900,33 @@ void t_dart_generator::generate_dart_struct_reader(ostream& out, t_struct* tstru scope_down(out, " else"); scope_up(out); - indent(out) << "TProtocolUtil.skip(iprot, field.type);" << endl; + indent(out) << "TProtocolUtil.skip(iprot, field.type);" << '\n'; scope_down(out); - indent(out) << "break;" << endl; + indent(out) << "break;" << '\n'; indent_down(); } // In the default case we skip the field - indent(out) << "default:" << endl; + indent(out) << "default:" << '\n'; indent_up(); - indent(out) << "TProtocolUtil.skip(iprot, field.type);" << endl; - indent(out) << "break;" << endl; + indent(out) << "TProtocolUtil.skip(iprot, field.type);" << '\n'; + indent(out) << "break;" << '\n'; indent_down(); scope_down(out); // Read field end marker - indent(out) << "iprot.readFieldEnd();" << endl; + indent(out) << "iprot.readFieldEnd();" << '\n'; scope_down(out); - indent(out) << "iprot.readStructEnd();" << endl2; + indent(out) << "iprot.readStructEnd();" << '\n' << '\n'; // in non-beans style, check for required fields of primitive type // (which can be checked here but not in the general validate method) indent(out) << "// check for required fields of primitive type, which can't be " - "checked in the validate method" << endl; + "checked in the validate method" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if ((*f_iter)->get_req() == t_field::T_REQUIRED && !type_can_be_null((*f_iter)->get_type())) { string field_name = get_member_name((*f_iter)->get_name()); @@ -937,15 +934,15 @@ void t_dart_generator::generate_dart_struct_reader(ostream& out, t_struct* tstru scope_up(out); indent(out) << " throw new TProtocolError(TProtocolErrorType.UNKNOWN, \"Required field '" << field_name - << "' was not found in serialized data! Struct: \" + toString());" << endl; - scope_down(out, endl2); + << "' was not found in serialized data! Struct: \" + toString());" << '\n'; + scope_down(out, "\n\n"); } } // performs various checks (e.g. check that all required fields are set) - indent(out) << "validate();" << endl; + indent(out) << "validate();" << '\n'; - scope_down(out, endl2); + scope_down(out, "\n\n"); } // generates dart method to perform various checks @@ -957,7 +954,7 @@ void t_dart_generator::generate_dart_validator(ostream& out, t_struct* tstruct) const vector& fields = tstruct->get_members(); vector::const_iterator f_iter; - indent(out) << "// check for required fields" << endl; + indent(out) << "// check for required fields" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if ((*f_iter)->get_req() == t_field::T_REQUIRED) { string field_name = get_member_name((*f_iter)->get_name()); @@ -966,17 +963,17 @@ void t_dart_generator::generate_dart_validator(ostream& out, t_struct* tstruct) scope_up(out); indent(out) << "throw new TProtocolError(TProtocolErrorType.UNKNOWN, \"Required field '" << field_name << "' was not present! Struct: \" + toString());" - << endl; + << '\n'; scope_down(out); } else { indent(out) << "// alas, we cannot check '" << field_name - << "' because it's a primitive and you chose the non-beans generator." << endl; + << "' because it's a primitive and you chose the non-beans generator." << '\n'; } } } // check that fields of type enum have valid values - indent(out) << "// check that fields of type enum have valid values" << endl; + indent(out) << "// check that fields of type enum have valid values" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { t_field* field = (*f_iter); t_type* type = field->get_type(); @@ -988,12 +985,12 @@ void t_dart_generator::generate_dart_validator(ostream& out, t_struct* tstruct) scope_up(out); indent(out) << "throw new TProtocolError(TProtocolErrorType.UNKNOWN, \"The field '" << field_name << "' has been assigned the invalid value " - << "$" << field_name << "\");" << endl; + << "$" << field_name << "\");" << '\n'; scope_down(out); } } - scope_down(out, endl2); + scope_down(out, "\n\n"); } /** @@ -1009,9 +1006,9 @@ void t_dart_generator::generate_dart_struct_writer(ostream& out, t_struct* tstru vector::const_iterator f_iter; // performs various checks (e.g. check that all required fields are set) - indent(out) << "validate();" << endl2; + indent(out) << "validate();" << '\n' << '\n'; - indent(out) << "oprot.writeStructBegin(_STRUCT_DESC);" << endl; + indent(out) << "oprot.writeStructBegin(_STRUCT_DESC);" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { string field_name = get_member_name((*f_iter)->get_name()); @@ -1027,13 +1024,13 @@ void t_dart_generator::generate_dart_struct_writer(ostream& out, t_struct* tstru } indent(out) << "oprot.writeFieldBegin(_" << constant_name((*f_iter)->get_name()) - << "_FIELD_DESC);" << endl; + << "_FIELD_DESC);" << '\n'; // Write field contents generate_serialize_field(out, *f_iter, "this."); // Write field closer - indent(out) << "oprot.writeFieldEnd();" << endl; + indent(out) << "oprot.writeFieldEnd();" << '\n'; if (null_allowed) { scope_down(out); @@ -1043,10 +1040,10 @@ void t_dart_generator::generate_dart_struct_writer(ostream& out, t_struct* tstru } } // Write the struct map - indent(out) << "oprot.writeFieldStop();" << endl << indent() << "oprot.writeStructEnd();" - << endl; + indent(out) << "oprot.writeFieldStop();" << '\n' << indent() << "oprot.writeStructEnd();" + << '\n'; - scope_down(out, endl2); + scope_down(out, "\n\n"); } /** @@ -1064,7 +1061,7 @@ void t_dart_generator::generate_dart_struct_result_writer(ostream& out, t_struct const vector& fields = tstruct->get_sorted_members(); vector::const_iterator f_iter; - indent(out) << "oprot.writeStructBegin(_STRUCT_DESC);" << endl2; + indent(out) << "oprot.writeStructBegin(_STRUCT_DESC);" << '\n' << '\n'; bool first = true; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { @@ -1079,23 +1076,23 @@ void t_dart_generator::generate_dart_struct_result_writer(ostream& out, t_struct scope_up(out); indent(out) << "oprot.writeFieldBegin(_" << constant_name((*f_iter)->get_name()) - << "_FIELD_DESC);" << endl; + << "_FIELD_DESC);" << '\n'; // Write field contents generate_serialize_field(out, *f_iter, "this."); // Write field closer - indent(out) << "oprot.writeFieldEnd();" << endl; + indent(out) << "oprot.writeFieldEnd();" << '\n'; scope_down(out, ""); } - out << endl; + out << '\n'; // Write the struct map - indent(out) << "oprot.writeFieldStop();" << endl << indent() - << "oprot.writeStructEnd();" << endl; + indent(out) << "oprot.writeFieldStop();" << '\n' << indent() + << "oprot.writeStructEnd();" << '\n'; - scope_down(out, endl2); + scope_down(out, "\n\n"); } void t_dart_generator::generate_generic_field_getters(std::ostream& out, @@ -1113,19 +1110,19 @@ void t_dart_generator::generate_generic_field_getters(std::ostream& out, t_field* field = *f_iter; std::string field_name = get_member_name(field->get_name()); - indent(out) << "case " << upcase_string(field_name) << ":" << endl; + indent(out) << "case " << upcase_string(field_name) << ":" << '\n'; indent_up(); - indent(out) << "return this." << field_name << ";" << endl; + indent(out) << "return this." << field_name << ";" << '\n'; indent_down(); } - indent(out) << "default:" << endl; + indent(out) << "default:" << '\n'; indent_up(); - indent(out) << "throw new ArgumentError(\"Field $fieldID doesn't exist!\");" << endl; + indent(out) << "throw new ArgumentError(\"Field $fieldID doesn't exist!\");" << '\n'; indent_down(); scope_down(out); // switch - scope_down(out, endl2); // method + scope_down(out, "\n\n"); // method } void t_dart_generator::generate_generic_field_setters(std::ostream& out, @@ -1145,31 +1142,31 @@ void t_dart_generator::generate_generic_field_setters(std::ostream& out, t_field* field = *f_iter; std::string field_name = get_member_name(field->get_name()); - indent(out) << "case " << upcase_string(field_name) << ":" << endl; + indent(out) << "case " << upcase_string(field_name) << ":" << '\n'; indent_up(); indent(out) << "if (value == null)"; scope_up(out); - indent(out) << "unset" << get_cap_name(field_name) << "();" << endl; + indent(out) << "unset" << get_cap_name(field_name) << "();" << '\n'; scope_down(out, " else"); scope_up(out); - indent(out) << "this." << field_name << " = value;" << endl; + indent(out) << "this." << field_name << " = value;" << '\n'; scope_down(out); - indent(out) << "break;" << endl; + indent(out) << "break;" << '\n'; indent_down(); - out << endl; + out << '\n'; } - indent(out) << "default:" << endl; + indent(out) << "default:" << '\n'; indent_up(); - indent(out) << "throw new ArgumentError(\"Field $fieldID doesn't exist!\");" << endl; + indent(out) << "throw new ArgumentError(\"Field $fieldID doesn't exist!\");" << '\n'; indent_down(); scope_down(out); // switch - scope_down(out, endl2); // method + scope_down(out, "\n\n"); // method } // Creates a generic isSet method that takes the field number as argument @@ -1179,7 +1176,7 @@ void t_dart_generator::generate_generic_isset_method(std::ostream& out, t_struct // create the isSet method indent(out) << "// Returns true if field corresponding to fieldID is set (has been assigned a " - "value) and false otherwise" << endl; + "value) and false otherwise" << '\n'; indent(out) << "bool isSet(int fieldID)"; scope_up(out); @@ -1188,19 +1185,19 @@ void t_dart_generator::generate_generic_isset_method(std::ostream& out, t_struct for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { t_field* field = *f_iter; - indent(out) << "case " << upcase_string(field->get_name()) << ":" << endl; + indent(out) << "case " << upcase_string(field->get_name()) << ":" << '\n'; indent_up(); - indent(out) << "return " << generate_isset_check(field) << ";" << endl; + indent(out) << "return " << generate_isset_check(field) << ";" << '\n'; indent_down(); } - indent(out) << "default:" << endl; + indent(out) << "default:" << '\n'; indent_up(); - indent(out) << "throw new ArgumentError(\"Field $fieldID doesn't exist!\");" << endl; + indent(out) << "throw new ArgumentError(\"Field $fieldID doesn't exist!\");" << '\n'; indent_down(); scope_down(out); // switch - scope_down(out, endl2); // method + scope_down(out, "\n\n"); // method } /** @@ -1219,37 +1216,37 @@ void t_dart_generator::generate_dart_bean_boilerplate(ostream& out, std::string field_name = get_member_name(field->get_name()); std::string cap_name = get_cap_name(field_name); - indent(out) << "// " << field_name << endl; + indent(out) << "// " << field_name << '\n'; // Simple getter generate_dart_doc(out, field); - indent(out) << type_name(type) << " get " << field_name << " => this._" << field_name << ";" << endl2; + indent(out) << type_name(type) << " get " << field_name << " => this._" << field_name << ";" << '\n' << '\n'; // Simple setter generate_dart_doc(out, field); indent(out) << "set " << field_name << "(" << type_name(type) << " " << field_name << ")"; scope_up(out); - indent(out) << "this._" << field_name << " = " << field_name << ";" << endl; + indent(out) << "this._" << field_name << " = " << field_name << ";" << '\n'; generate_isset_set(out, field); - scope_down(out, endl2); + scope_down(out, "\n\n"); // isSet method indent(out) << "bool is" << get_cap_name("set") << cap_name << "()"; if (type_can_be_null(type)) { - out << " => this." << field_name << " != null;" << endl2; + out << " => this." << field_name << " != null;" << '\n' << '\n'; } else { - out << " => this.__isset_" << field_name << ";" << endl2; + out << " => this.__isset_" << field_name << ";" << '\n' << '\n'; } // Unsetter indent(out) << "unset" << cap_name << "()"; scope_up(out); if (type_can_be_null(type)) { - indent(out) << "this." << field_name << " = null;" << endl; + indent(out) << "this." << field_name << " = null;" << '\n'; } else { - indent(out) << "this.__isset_" << field_name << " = false;" << endl; + indent(out) << "this.__isset_" << field_name << " = false;" << '\n'; } - scope_down(out, endl2); + scope_down(out, "\n\n"); } } @@ -1264,7 +1261,7 @@ void t_dart_generator::generate_dart_struct_tostring(ostream& out, scope_up(out); indent(out) << "StringBuffer ret = new StringBuffer(\"" - << tstruct->get_name() << "(\");" << endl2; + << tstruct->get_name() << "(\");" << '\n' << '\n'; const vector& fields = tstruct->get_members(); vector::const_iterator f_iter; @@ -1281,36 +1278,36 @@ void t_dart_generator::generate_dart_struct_tostring(ostream& out, std::string field_name = get_member_name(field->get_name()); if (!first) { - indent(out) << "ret.write(\", \");" << endl; + indent(out) << "ret.write(\", \");" << '\n'; } - indent(out) << "ret.write(\"" << field_name << ":\");" << endl; + indent(out) << "ret.write(\"" << field_name << ":\");" << '\n'; bool can_be_null = type_can_be_null(field->get_type()); if (can_be_null) { indent(out) << "if (this." << field_name << " == null)"; scope_up(out); - indent(out) << "ret.write(\"null\");" << endl; + indent(out) << "ret.write(\"null\");" << '\n'; scope_down(out, " else"); scope_up(out); } if (field->get_type()->is_binary()) { - indent(out) << "ret.write(\"BINARY\");" << endl; + indent(out) << "ret.write(\"BINARY\");" << '\n'; } else if (field->get_type()->is_enum()) { indent(out) << "String " << field_name << "_name = " << get_ttype_class_name(field->get_type()) - << ".VALUES_TO_NAMES[this." << field_name << "];" << endl; + << ".VALUES_TO_NAMES[this." << field_name << "];" << '\n'; indent(out) << "if (" << field_name << "_name != null)"; scope_up(out); - indent(out) << "ret.write(" << field_name << "_name);" << endl; - indent(out) << "ret.write(\" (\");" << endl; + indent(out) << "ret.write(" << field_name << "_name);" << '\n'; + indent(out) << "ret.write(\" (\");" << '\n'; scope_down(out); - indent(out) << "ret.write(this." << field_name << ");" << endl; + indent(out) << "ret.write(this." << field_name << ");" << '\n'; indent(out) << "if (" << field_name << "_name != null)"; scope_up(out); - indent(out) << "ret.write(\")\");" << endl; + indent(out) << "ret.write(\")\");" << '\n'; scope_down(out); } else { - indent(out) << "ret.write(this." << field_name << ");" << endl; + indent(out) << "ret.write(this." << field_name << ");" << '\n'; } if (can_be_null) { @@ -1320,15 +1317,15 @@ void t_dart_generator::generate_dart_struct_tostring(ostream& out, scope_down(out); } - out << endl; + out << '\n'; first = false; } - indent(out) << "ret.write(\")\");" << endl2; + indent(out) << "ret.write(\")\");" << '\n' << '\n'; - indent(out) << "return ret.toString();" << endl; + indent(out) << "return ret.toString();" << '\n'; - scope_down(out, endl2); + scope_down(out, "\n\n"); } /** @@ -1391,9 +1388,9 @@ void t_dart_generator::generate_service(t_service* tservice) { string f_service_name = src_dir_ + "/" + file_name + ".dart"; f_service_.open(f_service_name.c_str()); - f_service_ << autogen_comment() << dart_library(file_name) << endl; - f_service_ << service_imports() << dart_thrift_imports() << endl; - f_service_ << endl; + f_service_ << autogen_comment() << dart_library(file_name) << '\n'; + f_service_ << service_imports() << dart_thrift_imports() << '\n'; + f_service_ << '\n'; generate_service_interface(tservice); generate_service_client(tservice); @@ -1424,12 +1421,12 @@ void t_dart_generator::generate_service_interface(t_service* tservice) { vector functions = tservice->get_functions(); vector::iterator f_iter; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { - f_service_ << endl; + f_service_ << '\n'; generate_dart_doc(f_service_, *f_iter); - indent(f_service_) << function_signature(*f_iter) << ";" << endl; + indent(f_service_) << function_signature(*f_iter) << ";" << '\n'; } - scope_down(f_service_, endl2); + scope_down(f_service_, "\n\n"); } /** @@ -1465,31 +1462,31 @@ void t_dart_generator::generate_service_client(t_service* tservice) { indent(f_service_) << "class " << class_name << extends_client << " implements " << service_name_; scope_up(f_service_); - f_service_ << endl; + f_service_ << '\n'; indent(f_service_) << class_name << "(TProtocol iprot, [TProtocol oprot = null])"; if (!extends.empty()) { indent_up(); - f_service_ << endl; - indent(f_service_) << ": super(iprot, oprot);" << endl; + f_service_ << '\n'; + indent(f_service_) << ": super(iprot, oprot);" << '\n'; indent_down(); } else { scope_up(f_service_); - indent(f_service_) << "_iprot = iprot;" << endl; - indent(f_service_) << "_oprot = (oprot == null) ? iprot : oprot;" << endl; + indent(f_service_) << "_iprot = iprot;" << '\n'; + indent(f_service_) << "_oprot = (oprot == null) ? iprot : oprot;" << '\n'; scope_down(f_service_); } - f_service_ << endl; + f_service_ << '\n'; if (extends.empty()) { - indent(f_service_) << "TProtocol _iprot;" << endl2; - indent(f_service_) << "TProtocol get iprot => _iprot;" << endl2; - indent(f_service_) << "TProtocol _oprot;" << endl2; - indent(f_service_) << "TProtocol get oprot => _oprot;" << endl2; - indent(f_service_) << "int _seqid = 0;" << endl2; - indent(f_service_) << "int get seqid => _seqid;" << endl2; - indent(f_service_) << "int nextSeqid() => ++_seqid;" << endl2; + indent(f_service_) << "TProtocol _iprot;" << '\n' << '\n'; + indent(f_service_) << "TProtocol get iprot => _iprot;" << '\n' << '\n'; + indent(f_service_) << "TProtocol _oprot;" << '\n' << '\n'; + indent(f_service_) << "TProtocol get oprot => _oprot;" << '\n' << '\n'; + indent(f_service_) << "int _seqid = 0;" << '\n' << '\n'; + indent(f_service_) << "int get seqid => _seqid;" << '\n' << '\n'; + indent(f_service_) << "int nextSeqid() => ++_seqid;" << '\n' << '\n'; } // Generate client method implementations @@ -1510,40 +1507,40 @@ void t_dart_generator::generate_service_client(t_service* tservice) { // Serialize the request indent(f_service_) << "oprot.writeMessageBegin(new TMessage(\"" << (*f_iter)->get_name() << "\", " << ((*f_iter)->is_oneway() ? "TMessageType.ONEWAY" : "TMessageType.CALL") - << ", nextSeqid()));" << endl; - indent(f_service_) << argsname << " args = new " << argsname << "();" << endl; + << ", nextSeqid()));" << '\n'; + indent(f_service_) << argsname << " args = new " << argsname << "();" << '\n'; for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) { string arg_field_name = get_member_name((*fld_iter)->get_name()); indent(f_service_) << "args." << arg_field_name << " = " - << arg_field_name << ";" << endl; + << arg_field_name << ";" << '\n'; } - indent(f_service_) << "args.write(oprot);" << endl; - indent(f_service_) << "oprot.writeMessageEnd();" << endl2; + indent(f_service_) << "args.write(oprot);" << '\n'; + indent(f_service_) << "oprot.writeMessageEnd();" << '\n' << '\n'; - indent(f_service_) << "await oprot.transport.flush();" << endl2; + indent(f_service_) << "await oprot.transport.flush();" << '\n' << '\n'; if (!(*f_iter)->is_oneway()) { - indent(f_service_) << "TMessage msg = iprot.readMessageBegin();" << endl; + indent(f_service_) << "TMessage msg = iprot.readMessageBegin();" << '\n'; indent(f_service_) << "if (msg.type == TMessageType.EXCEPTION)"; scope_up(f_service_); - indent(f_service_) << "TApplicationError error = TApplicationError.read(iprot);" << endl; - indent(f_service_) << "iprot.readMessageEnd();" << endl; - indent(f_service_) << "throw error;" << endl; - scope_down(f_service_, endl2); + indent(f_service_) << "TApplicationError error = TApplicationError.read(iprot);" << '\n'; + indent(f_service_) << "iprot.readMessageEnd();" << '\n'; + indent(f_service_) << "throw error;" << '\n'; + scope_down(f_service_, "\n\n"); string result_class = get_result_class_name((*f_iter)->get_name()); - indent(f_service_) << result_class << " result = new " << result_class << "();" << endl; - indent(f_service_) << "result.read(iprot);" << endl; - indent(f_service_) << "iprot.readMessageEnd();" << endl; + indent(f_service_) << result_class << " result = new " << result_class << "();" << '\n'; + indent(f_service_) << "result.read(iprot);" << '\n'; + indent(f_service_) << "iprot.readMessageEnd();" << '\n'; // Careful, only return _result if not a void function if (!(*f_iter)->get_returntype()->is_void()) { indent(f_service_) << "if (result." << generate_isset_check("success") << ")"; scope_up(f_service_); - indent(f_service_) << "return result.success;" << endl; - scope_down(f_service_, endl2); + indent(f_service_) << "return result.success;" << '\n'; + scope_down(f_service_, "\n\n"); } t_struct* xs = (*f_iter)->get_xceptions(); @@ -1553,23 +1550,23 @@ void t_dart_generator::generate_service_client(t_service* tservice) { string result_field_name = get_member_name((*x_iter)->get_name()); indent(f_service_) << "if (result." << result_field_name << " != null)"; scope_up(f_service_); - indent(f_service_) << "throw result." << result_field_name << ";" << endl; + indent(f_service_) << "throw result." << result_field_name << ";" << '\n'; scope_down(f_service_); } // If you get here it's an exception, unless a void function if ((*f_iter)->get_returntype()->is_void()) { - indent(f_service_) << "return;" << endl; + indent(f_service_) << "return;" << '\n'; } else { indent(f_service_) << "throw new TApplicationError(TApplicationErrorType.MISSING_RESULT, \"" - << (*f_iter)->get_name() << " failed: unknown result\");" << endl; + << (*f_iter)->get_name() << " failed: unknown result\");" << '\n'; } } - scope_down(f_service_, endl2); + scope_down(f_service_, "\n\n"); } - scope_down(f_service_, endl2); + scope_down(f_service_, "\n\n"); } /** @@ -1583,7 +1580,7 @@ void t_dart_generator::generate_service_server(t_service* tservice) { vector::iterator f_iter; // typedef - indent(f_service_) << "typedef void ProcessFunction(int seqid, TProtocol iprot, TProtocol oprot);" << endl2; + indent(f_service_) << "typedef void ProcessFunction(int seqid, TProtocol iprot, TProtocol oprot);" << '\n' << '\n'; // Extends stuff string extends = ""; @@ -1602,57 +1599,57 @@ void t_dart_generator::generate_service_server(t_service* tservice) { indent(f_service_) << class_name << "(" << service_name_ << " iface)"; if (!extends.empty()) { indent_up(); - f_service_ << endl; + f_service_ << '\n'; indent(f_service_) << ": super(iface)"; indent_down(); } scope_up(f_service_); if (extends.empty()) { - indent(f_service_) << "iface_ = iface;" << endl; + indent(f_service_) << "iface_ = iface;" << '\n'; } for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { indent(f_service_) << "PROCESS_MAP[\"" << (*f_iter)->get_name() - << "\"] = " << get_member_name((*f_iter)->get_name()) << ";" << endl; + << "\"] = " << get_member_name((*f_iter)->get_name()) << ";" << '\n'; } - scope_down(f_service_, endl2); + scope_down(f_service_, "\n\n"); - indent(f_service_) << service_name_ << " iface_;" << endl; + indent(f_service_) << service_name_ << " iface_;" << '\n'; if (extends.empty()) { - indent(f_service_) << "final Map PROCESS_MAP = {};" << endl; + indent(f_service_) << "final Map PROCESS_MAP = {};" << '\n'; } - f_service_ << endl; + f_service_ << '\n'; // Generate the server implementation indent(f_service_) << "bool process(TProtocol iprot, TProtocol oprot)"; scope_up(f_service_); - indent(f_service_) << "TMessage msg = iprot.readMessageBegin();" << endl; - indent(f_service_) << "ProcessFunction fn = PROCESS_MAP[msg.name];" << endl; + indent(f_service_) << "TMessage msg = iprot.readMessageBegin();" << '\n'; + indent(f_service_) << "ProcessFunction fn = PROCESS_MAP[msg.name];" << '\n'; indent(f_service_) << "if (fn == null)"; scope_up(f_service_); - indent(f_service_) << "TProtocolUtil.skip(iprot, TType.STRUCT);" << endl; - indent(f_service_) << "iprot.readMessageEnd();" << endl; + indent(f_service_) << "TProtocolUtil.skip(iprot, TType.STRUCT);" << '\n'; + indent(f_service_) << "iprot.readMessageEnd();" << '\n'; indent(f_service_) << "TApplicationError x = new TApplicationError(TApplicationErrorType.UNKNOWN_METHOD, " - "\"Invalid method name: '\"+msg.name+\"'\");" << endl; - indent(f_service_) << "oprot.writeMessageBegin(new TMessage(msg.name, TMessageType.EXCEPTION, msg.seqid));" << endl; - indent(f_service_) << "x.write(oprot);" << endl; - indent(f_service_) << "oprot.writeMessageEnd();" << endl; - indent(f_service_) << "oprot.transport.flush();" << endl; - indent(f_service_) << "return true;" << endl; + "\"Invalid method name: '\"+msg.name+\"'\");" << '\n'; + indent(f_service_) << "oprot.writeMessageBegin(new TMessage(msg.name, TMessageType.EXCEPTION, msg.seqid));" << '\n'; + indent(f_service_) << "x.write(oprot);" << '\n'; + indent(f_service_) << "oprot.writeMessageEnd();" << '\n'; + indent(f_service_) << "oprot.transport.flush();" << '\n'; + indent(f_service_) << "return true;" << '\n'; scope_down(f_service_); - indent(f_service_) << "fn(msg.seqid, iprot, oprot);" << endl; - indent(f_service_) << "return true;" << endl; - scope_down(f_service_, endl2); // process function + indent(f_service_) << "fn(msg.seqid, iprot, oprot);" << '\n'; + indent(f_service_) << "return true;" << '\n'; + scope_down(f_service_, "\n\n"); // process function // Generate the process subfunctions for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { generate_process_function(tservice, *f_iter); } - scope_down(f_service_, endl2); // class + scope_down(f_service_, "\n\n"); // class } /** @@ -1700,16 +1697,16 @@ void t_dart_generator::generate_process_function(t_service* tservice, t_function string argsname = get_args_class_name(tfunction->get_name()); string resultname = get_result_class_name(tfunction->get_name()); - indent(f_service_) << argsname << " args = new " << argsname << "();" << endl; - indent(f_service_) << "args.read(iprot);" << endl; - indent(f_service_) << "iprot.readMessageEnd();" << endl; + indent(f_service_) << argsname << " args = new " << argsname << "();" << '\n'; + indent(f_service_) << "args.read(iprot);" << '\n'; + indent(f_service_) << "iprot.readMessageEnd();" << '\n'; t_struct* xs = tfunction->get_xceptions(); const std::vector& xceptions = xs->get_members(); vector::const_iterator x_iter; if (!tfunction->is_oneway()) { - indent(f_service_) << resultname << " result = new " << resultname << "();" << endl; + indent(f_service_) << resultname << " result = new " << resultname << "();" << '\n'; } if (!tfunction->is_oneway() && xceptions.size() > 0) { @@ -1736,7 +1733,7 @@ void t_dart_generator::generate_process_function(t_service* tservice, t_function } f_service_ << "args." << get_member_name((*f_iter)->get_name()); } - f_service_ << ");" << endl; + f_service_ << ");" << '\n'; if (!tfunction->is_oneway() && xceptions.size() > 0) { for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { @@ -1747,36 +1744,36 @@ void t_dart_generator::generate_process_function(t_service* tservice, t_function scope_up(f_service_); if (!tfunction->is_oneway()) { indent(f_service_) << "result." << result_field_name << " = " - << result_field_name << ";" << endl; + << result_field_name << ";" << '\n'; } } scope_down(f_service_, " "); f_service_ << "catch (th)"; scope_up(f_service_); - indent(f_service_) << "// Internal error" << endl; + indent(f_service_) << "// Internal error" << '\n'; indent(f_service_) << "TApplicationError x = new " "TApplicationError(TApplicationErrorType.INTERNAL_ERROR, \"Internal error processing " - << tfunction->get_name() << "\");" << endl; + << tfunction->get_name() << "\");" << '\n'; indent(f_service_) << "oprot.writeMessageBegin(new TMessage(\"" << tfunction->get_name() - << "\", TMessageType.EXCEPTION, seqid));" << endl; - indent(f_service_) << "x.write(oprot);" << endl; - indent(f_service_) << "oprot.writeMessageEnd();" << endl; - indent(f_service_) << "oprot.transport.flush();" << endl; - indent(f_service_) << "return;" << endl; + << "\", TMessageType.EXCEPTION, seqid));" << '\n'; + indent(f_service_) << "x.write(oprot);" << '\n'; + indent(f_service_) << "oprot.writeMessageEnd();" << '\n'; + indent(f_service_) << "oprot.transport.flush();" << '\n'; + indent(f_service_) << "return;" << '\n'; scope_down(f_service_); } if (tfunction->is_oneway()) { - indent(f_service_) << "return;" << endl; + indent(f_service_) << "return;" << '\n'; } else { indent(f_service_) << "oprot.writeMessageBegin(new TMessage(\"" << tfunction->get_name() - << "\", TMessageType.REPLY, seqid));" << endl; - indent(f_service_) << "result.write(oprot);" << endl; - indent(f_service_) << "oprot.writeMessageEnd();" << endl; - indent(f_service_) << "oprot.transport.flush();" << endl; + << "\", TMessageType.REPLY, seqid));" << '\n'; + indent(f_service_) << "result.write(oprot);" << '\n'; + indent(f_service_) << "oprot.writeMessageEnd();" << '\n'; + indent(f_service_) << "oprot.transport.flush();" << '\n'; } - scope_down(f_service_, endl2); + scope_down(f_service_, "\n\n"); } /** @@ -1840,7 +1837,7 @@ void t_dart_generator::generate_deserialize_field(ostream& out, t_field* tfield, } else if (type->is_enum()) { out << "readI32();"; } - out << endl; + out << '\n'; } else { printf("DO NOT KNOW HOW TO DESERIALIZE FIELD '%s' TYPE '%s'\n", field_name.c_str(), @@ -1852,8 +1849,8 @@ void t_dart_generator::generate_deserialize_field(ostream& out, t_field* tfield, * Generates an unserializer for a struct, invokes read() */ void t_dart_generator::generate_deserialize_struct(ostream& out, t_struct* tstruct, string prefix) { - indent(out) << prefix << " = new " << type_name(tstruct) << "();" << endl; - indent(out) << prefix << ".read(iprot);" << endl; + indent(out) << prefix << " = new " << type_name(tstruct) << "();" << '\n'; + indent(out) << prefix << ".read(iprot);" << '\n'; } /** @@ -1875,14 +1872,14 @@ void t_dart_generator::generate_deserialize_container(ostream& out, t_type* ttyp // Declare variables, read header if (ttype->is_map()) { - indent(out) << "TMap " << obj << " = iprot.readMapBegin();" << endl; + indent(out) << "TMap " << obj << " = iprot.readMapBegin();" << '\n'; } else if (ttype->is_set()) { - indent(out) << "TSet " << obj << " = iprot.readSetBegin();" << endl; + indent(out) << "TSet " << obj << " = iprot.readSetBegin();" << '\n'; } else if (ttype->is_list()) { - indent(out) << "TList " << obj << " = iprot.readListBegin();" << endl; + indent(out) << "TList " << obj << " = iprot.readListBegin();" << '\n'; } - indent(out) << prefix << " = new " << type_name(ttype) << "();" << endl; + indent(out) << prefix << " = new " << type_name(ttype) << "();" << '\n'; // For loop iterates over elements string i = tmp("_i"); @@ -1903,11 +1900,11 @@ void t_dart_generator::generate_deserialize_container(ostream& out, t_type* ttyp // Read container end if (ttype->is_map()) { - indent(out) << "iprot.readMapEnd();" << endl; + indent(out) << "iprot.readMapEnd();" << '\n'; } else if (ttype->is_set()) { - indent(out) << "iprot.readSetEnd();" << endl; + indent(out) << "iprot.readSetEnd();" << '\n'; } else if (ttype->is_list()) { - indent(out) << "iprot.readListEnd();" << endl; + indent(out) << "iprot.readListEnd();" << '\n'; } scope_down(out); @@ -1922,13 +1919,13 @@ void t_dart_generator::generate_deserialize_map_element(ostream& out, t_map* tma t_field fkey(tmap->get_key_type(), key); t_field fval(tmap->get_val_type(), val); - indent(out) << declare_field(&fkey) << endl; - indent(out) << declare_field(&fval) << endl; + indent(out) << declare_field(&fkey) << '\n'; + indent(out) << declare_field(&fval) << '\n'; generate_deserialize_field(out, &fkey); generate_deserialize_field(out, &fval); - indent(out) << prefix << "[" << key << "] = " << val << ";" << endl; + indent(out) << prefix << "[" << key << "] = " << val << ";" << '\n'; } /** @@ -1938,11 +1935,11 @@ void t_dart_generator::generate_deserialize_set_element(ostream& out, t_set* tse string elem = tmp("_elem"); t_field felem(tset->get_elem_type(), elem); - indent(out) << declare_field(&felem) << endl; + indent(out) << declare_field(&felem) << '\n'; generate_deserialize_field(out, &felem); - indent(out) << prefix << ".add(" << elem << ");" << endl; + indent(out) << prefix << ".add(" << elem << ");" << '\n'; } /** @@ -1954,11 +1951,11 @@ void t_dart_generator::generate_deserialize_list_element(ostream& out, string elem = tmp("_elem"); t_field felem(tlist->get_elem_type(), elem); - indent(out) << declare_field(&felem) << endl; + indent(out) << declare_field(&felem) << '\n'; generate_deserialize_field(out, &felem); - indent(out) << prefix << ".add(" << elem << ");" << endl; + indent(out) << prefix << ".add(" << elem << ");" << '\n'; } /** @@ -2022,7 +2019,7 @@ void t_dart_generator::generate_serialize_field(ostream& out, t_field* tfield, s } else if (type->is_enum()) { out << "writeI32(" << name << ");"; } - out << endl; + out << '\n'; } else { printf("DO NOT KNOW HOW TO SERIALIZE FIELD '%s%s' TYPE '%s'\n", prefix.c_str(), @@ -2039,7 +2036,7 @@ void t_dart_generator::generate_serialize_field(ostream& out, t_field* tfield, s */ void t_dart_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix) { (void)tstruct; - indent(out) << prefix << ".write(oprot);" << endl; + indent(out) << prefix << ".write(oprot);" << '\n'; } /** @@ -2056,14 +2053,14 @@ void t_dart_generator::generate_serialize_container(ostream& out, t_type* ttype, string iter = tmp("_key"); indent(out) << "oprot.writeMapBegin(new TMap(" << type_to_enum(((t_map*)ttype)->get_key_type()) << ", " << type_to_enum(((t_map*)ttype)->get_val_type()) << ", " << prefix << ".length));" - << endl; + << '\n'; } else if (ttype->is_set()) { indent(out) << "oprot.writeSetBegin(new TSet(" << type_to_enum(((t_set*)ttype)->get_elem_type()) - << ", " << prefix << ".length));" << endl; + << ", " << prefix << ".length));" << '\n'; } else if (ttype->is_list()) { indent(out) << "oprot.writeListBegin(new TList(" << type_to_enum(((t_list*)ttype)->get_elem_type()) << ", " << prefix << ".length));" - << endl; + << '\n'; } string iter = tmp("elem"); @@ -2086,11 +2083,11 @@ void t_dart_generator::generate_serialize_container(ostream& out, t_type* ttype, scope_down(out); if (ttype->is_map()) { - indent(out) << "oprot.writeMapEnd();" << endl; + indent(out) << "oprot.writeMapEnd();" << '\n'; } else if (ttype->is_set()) { - indent(out) << "oprot.writeSetEnd();" << endl; + indent(out) << "oprot.writeSetEnd();" << '\n'; } else if (ttype->is_list()) { - indent(out) << "oprot.writeListEnd();" << endl; + indent(out) << "oprot.writeListEnd();" << '\n'; } scope_down(out); @@ -2496,7 +2493,7 @@ std::string t_dart_generator::generate_isset_check(std::string field_name) { void t_dart_generator::generate_isset_set(ostream& out, t_field* field) { if (!type_can_be_null(field->get_type())) { string field_name = get_member_name(field->get_name()); - indent(out) << "this.__isset_" << field_name << " = true;" << endl; + indent(out) << "this.__isset_" << field_name << " = true;" << '\n'; } } diff --git a/compiler/cpp/src/thrift/generate/t_delphi_generator.cc b/compiler/cpp/src/thrift/generate/t_delphi_generator.cc index c91ff332eab..cc6a460aded 100644 --- a/compiler/cpp/src/thrift/generate/t_delphi_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_delphi_generator.cc @@ -53,8 +53,6 @@ using std::string; using std::stringstream; using std::vector; -static const string endl = "\n"; // avoid ostream << std::endl flushes - class t_delphi_generator : public t_oop_generator { public: t_delphi_generator(t_program* program, @@ -68,7 +66,6 @@ class t_delphi_generator : public t_oop_generator { has_const = false; std::map::const_iterator iter; - ansistr_binary_ = false; register_types_ = false; constprefix_ = false; old_names_ = false; @@ -78,10 +75,7 @@ class t_delphi_generator : public t_oop_generator { com_types_ = false; rtti_ = false; for( iter = parsed_options.begin(); iter != parsed_options.end(); ++iter) { - if( iter->first.compare("ansistr_binary") == 0) { - ansistr_binary_ = true; - pwarning(0, "The 'ansistr_binary' option is deprecated."); - } else if( iter->first.compare("register_types") == 0) { + if( iter->first.compare("register_types") == 0) { register_types_ = true; } else if( iter->first.compare("old_names") == 0) { old_names_ = true; @@ -102,10 +96,6 @@ class t_delphi_generator : public t_oop_generator { } } - if(com_types_ && ansistr_binary_) { - throw "com_types and ansistr_binary are mutually exclusive"; - } - out_dir_base_ = "gen-delphi"; escape_.clear(); escape_['\''] = "''"; @@ -124,13 +114,11 @@ class t_delphi_generator : public t_oop_generator { 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); void generate_delphi_property(ostream& out, bool struct_is_exception, t_field* tfield, - bool isPublic, - std::string fieldPrefix = ""); + bool isPublic); void generate_delphi_isset_reader_writer_definition(ostream& out, t_field* tfield, bool is_xception); void generate_delphi_property_reader_definition(ostream& out, t_field* tfield, @@ -152,9 +140,7 @@ class t_delphi_generator : public t_oop_generator { t_field* tfield, std::string fieldPrefix, bool is_xception_class, - bool is_union, - bool is_xception_factory, - std::string xception_factory_name); + bool is_union); void generate_delphi_clear_union_value(ostream& out, std::string cls_prefix, std::string name, @@ -162,44 +148,33 @@ class t_delphi_generator : public t_oop_generator { t_field* tfield, std::string fieldPrefix, bool is_xception_class, - bool is_union, - bool is_xception_factory, - std::string xception_factory_name); + bool is_union); void generate_delphi_isset_reader_writer_impl(ostream& out, - std::string cls_prefix, - std::string name, - t_type* type, - t_field* tfield, - std::string fieldPrefix, - bool is_xception); + std::string cls_prefix, + std::string name, + t_type* type, + t_field* tfield, + std::string fieldPrefix, + bool is_xception_class); void generate_delphi_struct_writer_impl(ostream& out, std::string cls_prefix, t_struct* tstruct, - bool is_exception, - bool is_x_factory); - void generate_delphi_struct_result_writer_impl(ostream& out, - std::string cls_prefix, - t_struct* tstruct, - bool is_exception, - bool is_x_factory); + bool is_exception); void generate_delphi_struct_tostring_impl(ostream& out, std::string cls_prefix, t_struct* tstruct, - bool is_exception, - bool is_x_factory); + bool is_exception); void add_delphi_uses_list(string unitname); void generate_delphi_struct_reader_impl(ostream& out, std::string cls_prefix, t_struct* tstruct, - bool is_exception, - bool is_x_factory); - void generate_delphi_create_exception_impl(ostream& out, - string cls_prefix, - t_struct* tstruct, - bool is_exception); + bool is_exception); + + bool is_deprecated(std::map>& annotations); + std::string render_deprecation_attribute(std::map>& annotations, std::string prefix, std::string postfix); bool const_needs_var(t_type* type); void print_const_prop(std::ostream& out, string name, t_type* type, t_const_value* value); @@ -208,12 +183,14 @@ class t_delphi_generator : public t_oop_generator { std::ostream& out, std::string name, t_type* type, - t_const_value* value); + t_const_value* value, + bool is_const_class); void initialize_field(std::ostream& vars, std::ostream& out, std::string name, t_type* type, - t_const_value* value); + t_const_value* value, + bool is_const_class); void finalize_field(std::ostream& out, std::string name, t_type* type, @@ -221,9 +198,9 @@ class t_delphi_generator : public t_oop_generator { std::string cls_nm = ""); std::string render_const_value(std::ostream& local_vars, std::ostream& out, - std::string name, t_type* type, - t_const_value* value); + t_const_value* value, + bool guidAsLiteral); void print_const_def_value(std::ostream& vars, std::ostream& out, std::string name, @@ -232,36 +209,27 @@ class t_delphi_generator : public t_oop_generator { std::string cls_nm = ""); std::string make_constants_classname(); - void generate_delphi_struct(t_struct* tstruct, bool is_exception); + void generate_delphi_struct(t_struct* tstruct); + void generate_delphi_exception(t_struct* tstruct); void generate_delphi_struct_impl(ostream& out, std::string cls_prefix, t_struct* tstruct, - bool is_exception, - bool is_result = false, - bool is_x_factory = false); + bool is_result, + bool is_const_class); + void generate_delphi_exception_impl(ostream& out, + std::string cls_prefix, + t_struct* tstruct); void print_delphi_struct_type_factory_func(ostream& out, t_struct* tstruct); void generate_delphi_struct_type_factory(ostream& out, std::string cls_prefix, - t_struct* tstruct, - bool is_exception, - bool is_result = false, - bool is_x_factory = false); + t_struct* tstruct); void generate_delphi_struct_type_factory_registration(ostream& out, std::string cls_prefix, - t_struct* tstruct, - bool is_exception, - bool is_result = false, - bool is_x_factory = false); + t_struct* tstruct); void generate_delphi_struct_definition(std::ostream& out, - t_struct* tstruct, - bool is_xception = false, - bool in_class = false, - bool is_result = false, - bool is_x_factory = false); - void generate_delphi_struct_reader(std::ostream& out, t_struct* tstruct); - void generate_delphi_struct_result_writer(std::ostream& out, t_struct* tstruct); - void generate_delphi_struct_writer(std::ostream& out, t_struct* tstruct); - void generate_delphi_struct_tostring(std::ostream& out, t_struct* tstruct); + t_struct* tstruct); + void generate_delphi_exception_definition(std::ostream& out, + t_struct* tstruct); void generate_function_helpers(t_function* tfunction); void generate_service_interface(t_service* tservice); @@ -335,13 +303,10 @@ class t_delphi_generator : public t_oop_generator { std::ostream& local_vars); void delphi_type_usings(std::ostream& out); - std::string delphi_thrift_usings(); std::string type_name(t_type* ttype, bool b_cls = false, - bool b_no_postfix = false, - bool b_exception_factory = false, - bool b_full_exception_factory = false); + bool b_no_postfix = false); std::string normalize_clsnm(std::string name, std::string prefix, bool b_no_check_keyword = false); @@ -351,7 +316,6 @@ class t_delphi_generator : public t_oop_generator { std::string base_type_name(t_base_type* tbase); std::string declare_field(t_field* tfield, - bool init = false, std::string prefix = "", bool is_xception_class = false); std::string function_signature(t_function* tfunction, @@ -365,12 +329,6 @@ class t_delphi_generator : public t_oop_generator { std::string prop_name(std::string name, bool is_xception = false, std::string prefix = ""); std::string constructor_param_name(string name); - void write_enum(std::string line); - void write_forward_decr(std::string line); - void write_const(std::string line); - void write_struct(std::string line); - void write_service(std::string line); - 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" @@ -387,10 +345,7 @@ class t_delphi_generator : public t_oop_generator { void generate_delphi_docstring_comment(std::ostream& out, string contents); bool type_can_be_null(t_type* ttype) { - while (ttype->is_typedef()) { - ttype = ((t_typedef*)ttype)->get_type(); - } - + ttype = ttype->get_true_type(); return ttype->is_container() || ttype->is_struct() || ttype->is_xception(); } @@ -417,37 +372,38 @@ class t_delphi_generator : public t_oop_generator { const std::string DELPHI_KEYWORDS[81] = { // keywords - "and", "array", "as", "asm", "at", "automated", "begin", "case", "class", "const", "constructor", - "destructor", "dispinterface", "div", "do", "downto", "else", "end", "except", "exports", "file", - "finalization", "finally", "for", "function", "goto", "if", "implementation", "in", "inherited", - "initialization", "inline", "interface", "is", "label", "library", "mod", "nil", "not", "object", - "of", "on", "or", "out", "packed", "private", "procedure", "program", "property", "protected", - "public", "published", "raise", "record", "repeat", "resourcestring", "set", "shl", "shr", "string", + "and", "array", "as", "asm", "at", "automated", "begin", "case", "class", "const", "constructor", + "destructor", "dispinterface", "div", "do", "downto", "else", "end", "except", "exports", "file", + "finalization", "finally", "for", "function", "goto", "if", "implementation", "in", "inherited", + "initialization", "inline", "interface", "is", "label", "library", "mod", "nil", "not", "object", + "of", "on", "or", "out", "packed", "private", "procedure", "program", "property", "protected", + "public", "published", "raise", "record", "repeat", "resourcestring", "set", "shl", "shr", "string", "then", "threadvar", "to", "try", "type", "unit", "until", "uses", "var", "while", "with", "xor", // predefined types (lowercase!) "ansistring", "boolean", "double", "int64", "integer", "shortint", "smallint", "string", "unicodestring" }; // reserved variables and types (lowercase!) - const std::string DELPHI_RESERVED_NAMES[8] = { - "result", "system", "sysutils", "tbytes", "tclass", "thrift", "tinterfacedobject", "tobject" + const std::string DELPHI_RESERVED_NAMES[11] = { + "result", "system", "sysutils", "types", "texception", "tbytes", "tclass", "thrift", "tinterfacedobject", + "tobject", "ttask" }; // reserved method names (lowercase!) const std::string DELPHI_RESERVED_METHOD[31] = { - "afterconstruction", "beforedestruction", "classinfo", "classname", "classnameis", "classparent", - "classtype", "cleanupinstance", "create", "defaulthandler", "destroy", "dispatch", "equals", - "fieldaddress", "free", "freeinstance", "gethashcode", "getinterface", "getinterfaceentry", - "getinterfacetable", "inheritsfrom", "initinstance", "instancesize", "methodaddress", "methodname", + "afterconstruction", "beforedestruction", "classinfo", "classname", "classnameis", "classparent", + "classtype", "cleanupinstance", "create", "defaulthandler", "destroy", "dispatch", "equals", + "fieldaddress", "free", "freeinstance", "gethashcode", "getinterface", "getinterfaceentry", + "getinterfacetable", "inheritsfrom", "initinstance", "instancesize", "methodaddress", "methodname", "newinstance", "read", "safecallexception", "tostring", "unitname", "write" }; // reserved exception class method names (lowercase!) - const std::string DELPHI_RESERVED_METHOD_EXCEPTION[23] = { - "setinnerexception", "setstackinfo", "getstacktrace", "raisingexception", "createfmt", "createres", - "createresfmt", "createhelp", "createfmthelp", "createreshelp", "createresfmthelp", "getbaseexception", - "baseexception", "helpcontext", "innerexception", "message", "stacktrace", "stackinfo", - "getexceptionstackinfoproc", "getstackinfostringproc", "cleanupstackinfoproc", "raiseouterexception", + const std::string DELPHI_RESERVED_METHOD_EXCEPTION[24] = { + "setinnerexception", "setstackinfo", "getstacktrace", "raisingexception", "createfmt", "createres", + "createresfmt", "createhelp", "createfmthelp", "createreshelp", "createresfmthelp", "getbaseexception", + "baseexception", "helpcontext", "innerexception", "exceptiondata", "message", "stacktrace", "stackinfo", + "getexceptionstackinfoproc", "getstackinfostringproc", "cleanupstackinfoproc", "raiseouterexception", "throwouterexception" }; @@ -468,7 +424,6 @@ class t_delphi_generator : public t_oop_generator { void init_known_types_list(); bool is_void(t_type* type); int indent_impl_; - bool ansistr_binary_; bool register_types_; bool constprefix_; bool old_names_; @@ -637,10 +592,10 @@ std::string t_delphi_generator::normalize_name(std::string name, } // neither reserved nor keyword? - if (!(b_reserved || b_keyword)) { + if (!(b_reserved || b_keyword)) { return name; } - + // apply the rule: old style '_' postfix or more modern '&' prefix? // underscore always on non-keywords or when explicitly asked via arg if( (!b_keyword) || old_names_ || b_force_underscore) { @@ -695,8 +650,9 @@ void t_delphi_generator::init_generator() { unitname = include->get_name(); nsname = include->get_namespace("delphi"); if ("" != nsname) { - unitname = normalize_name(nsname,false,false,true/*force underscore*/); + unitname = nsname; } + unitname = normalize_name(unitname,false,false,true/*force underscore*/); add_delphi_uses_list(unitname); } @@ -716,25 +672,25 @@ void t_delphi_generator::close_generator() { } unitname = normalize_name(unitname,false,false,true/*force underscore*/); - + std::string f_name = get_out_dir() + "/" + unitname + ".pas"; ofstream_with_content_based_conditional_update f_all; f_all.open(f_name); - f_all << autogen_comment() << endl; + f_all << autogen_comment() << '\n'; generate_delphi_doc(f_all, program_); - f_all << "unit " << unitname << ";" << endl << endl; - f_all << "{$WARN SYMBOL_DEPRECATED OFF}" << endl; + f_all << "unit " << unitname << ";" << '\n' << '\n'; + f_all << "{$WARN SYMBOL_DEPRECATED OFF}" << '\n'; if(com_types_) { - f_all << "{$MINENUMSIZE 4}" << endl; + f_all << "{$MINENUMSIZE 4}" << '\n'; } if(rtti_) { - f_all << "{$IFOPT M+} {$DEFINE TYPEINFO_WAS_ON} {$ELSE} {$UNDEF TYPEINFO_WAS_ON} {$ENDIF}" << endl; + f_all << "{$IFOPT M+} {$DEFINE TYPEINFO_WAS_ON} {$ELSE} {$UNDEF TYPEINFO_WAS_ON} {$ENDIF}" << '\n'; } - f_all << endl; - f_all << "interface" << endl << endl; - f_all << "uses" << endl; + f_all << '\n'; + f_all << "interface" << '\n' << '\n'; + f_all << "uses" << '\n'; indent_up(); @@ -742,12 +698,12 @@ void t_delphi_generator::close_generator() { for (s_iter = uses_list.begin(); s_iter != uses_list.end(); ++s_iter) { if (s_iter != uses_list.begin()) { f_all << ","; - f_all << endl; + f_all << '\n'; } indent(f_all) << *s_iter; } - f_all << ";" << endl << endl; + f_all << ";" << '\n' << '\n'; indent_down(); @@ -758,71 +714,70 @@ void t_delphi_generator::close_generator() { } } - f_all << "const" << endl; + f_all << "const" << '\n'; indent_up(); - indent(f_all) << "c" << tmp_unit << "_Option_AnsiStr_Binary = " << (ansistr_binary_ ? "True" : "False") << ";" << endl; - indent(f_all) << "c" << tmp_unit << "_Option_Register_Types = " << (register_types_ ? "True" : "False") << ";" << endl; - indent(f_all) << "c" << tmp_unit << "_Option_ConstPrefix = " << (constprefix_ ? "True" : "False") << ";" << endl; - indent(f_all) << "c" << tmp_unit << "_Option_Events = " << (events_ ? "True" : "False") << ";" << endl; - indent(f_all) << "c" << tmp_unit << "_Option_XmlDoc = " << (xmldoc_ ? "True" : "False") << ";" << endl; - indent(f_all) << "c" << tmp_unit << "_Option_Async = " << (async_ ? "True" : "False") << ";" << endl; - indent(f_all) << "c" << tmp_unit << "_Option_COM_types = " << (com_types_ ? "True" : "False") << ";" << endl; - indent(f_all) << "c" << tmp_unit << "_Option_Old_Names = " << (old_names_ ? "True" : "False") << ";" << endl; - indent(f_all) << "c" << tmp_unit << "_Option_RTTI = " << (rtti_ ? "True" : "False") << ";" << endl; + indent(f_all) << "c" << tmp_unit << "_Option_Register_Types = " << (register_types_ ? "True" : "False") << ";" << '\n'; + indent(f_all) << "c" << tmp_unit << "_Option_ConstPrefix = " << (constprefix_ ? "True" : "False") << ";" << '\n'; + indent(f_all) << "c" << tmp_unit << "_Option_Events = " << (events_ ? "True" : "False") << ";" << '\n'; + indent(f_all) << "c" << tmp_unit << "_Option_XmlDoc = " << (xmldoc_ ? "True" : "False") << ";" << '\n'; + indent(f_all) << "c" << tmp_unit << "_Option_Async = " << (async_ ? "True" : "False") << ";" << '\n'; + indent(f_all) << "c" << tmp_unit << "_Option_COM_types = " << (com_types_ ? "True" : "False") << ";" << '\n'; + indent(f_all) << "c" << tmp_unit << "_Option_Old_Names = " << (old_names_ ? "True" : "False") << ";" << '\n'; + indent(f_all) << "c" << tmp_unit << "_Option_RTTI = " << (rtti_ ? "True" : "False") << ";" << '\n'; indent_down(); - f_all << endl; - f_all << "type" << endl; + f_all << '\n'; + f_all << "type" << '\n'; if (has_forward) { - f_all << s_forward_decr.str() << endl; + f_all << s_forward_decr.str() << '\n'; } if (has_enum) { - indent(f_all) << endl; - indent(f_all) << "{$SCOPEDENUMS ON}" << endl << endl; + indent(f_all) << '\n'; + indent(f_all) << "{$SCOPEDENUMS ON}" << '\n' << '\n'; f_all << s_enum.str(); - indent(f_all) << "{$SCOPEDENUMS OFF}" << endl << endl; + indent(f_all) << "{$SCOPEDENUMS OFF}" << '\n' << '\n'; } f_all << s_struct.str(); f_all << s_service.str(); f_all << s_const.str(); - f_all << "implementation" << endl << endl; + f_all << "implementation" << '\n' << '\n'; f_all << s_struct_impl.str(); f_all << s_service_impl.str(); f_all << s_const_impl.str(); if (register_types_) { - f_all << endl; - f_all << "// Type factory methods and registration" << endl; + f_all << '\n'; + f_all << "// Type factory methods and registration" << '\n'; f_all << s_type_factory_funcs.str(); - f_all << "procedure RegisterTypeFactories;" << endl; - f_all << "begin" << endl; + f_all << "procedure RegisterTypeFactories;" << '\n'; + f_all << "begin" << '\n'; f_all << s_type_factory_registration.str(); - f_all << "end;" << endl; + f_all << "end;" << '\n'; } - f_all << endl; + f_all << '\n'; string constants_class = make_constants_classname(); - f_all << "initialization" << endl; + f_all << "initialization" << '\n'; if (has_const) { - f_all << "{$IF CompilerVersion < 21.0} // D2010" << endl; - f_all << " " << constants_class.c_str() << "_Initialize;" << endl; - f_all << "{$IFEND}" << endl; + f_all << "{$IF CompilerVersion < 21.0} // D2010" << '\n'; + f_all << " " << constants_class.c_str() << "_Initialize;" << '\n'; + f_all << "{$IFEND}" << '\n'; } if (register_types_) { - f_all << " RegisterTypeFactories;" << endl; + f_all << " RegisterTypeFactories;" << '\n'; } - f_all << endl; + f_all << '\n'; - f_all << "finalization" << endl; + f_all << "finalization" << '\n'; if (has_const) { - f_all << "{$IF CompilerVersion < 21.0} // D2010" << endl; - f_all << " " << constants_class.c_str() << "_Finalize;" << endl; - f_all << "{$IFEND}" << endl; + f_all << "{$IF CompilerVersion < 21.0} // D2010" << '\n'; + f_all << " " << constants_class.c_str() << "_Finalize;" << '\n'; + f_all << "{$IFEND}" << '\n'; } - f_all << endl << endl; + f_all << '\n' << '\n'; - f_all << "end." << endl; + f_all << "end." << '\n'; f_all.close(); if (!typedefs_pending.empty()) { @@ -838,8 +793,8 @@ void t_delphi_generator::close_generator() { void t_delphi_generator::delphi_type_usings(ostream& out) { indent_up(); indent(out) << "Classes, SysUtils, Generics.Collections, Thrift.Collections, Thrift.Protocol," - << endl; - indent(out) << "Thrift.Transport;" << endl << endl; + << '\n'; + indent(out) << "Thrift.Transport;" << '\n' << '\n'; indent_down(); } @@ -848,11 +803,11 @@ void t_delphi_generator::generate_forward_declaration(t_struct* tstruct) { has_forward = true; pdebug("forward declaration of %s\n", type_name(tstruct).c_str()); - string what = tstruct->is_xception() ? "class" : "interface"; - indent_up(); - indent(s_forward_decr) << type_name(tstruct, tstruct->is_xception(), true) << " = " << what << ";" - << endl; + indent(s_forward_decr) << type_name(tstruct, false, true) << " = interface;" << '\n'; + if( tstruct->is_xception()) { + indent(s_forward_decr) << type_name(tstruct, true, true) << " = class;" << '\n'; + } indent_down(); add_defined_type(tstruct); @@ -877,7 +832,7 @@ void t_delphi_generator::generate_typedef(t_typedef* ttypedef) { // if( ! container) // s_struct << "type "; //the "type A = type B" syntax leads to E2574 with generics - s_struct << type_name(ttypedef->get_type()) << ";" << endl << endl; + s_struct << type_name(ttypedef->get_type()) << ";" << '\n' << '\n'; indent_down(); add_defined_type(ttypedef); @@ -958,7 +913,7 @@ void t_delphi_generator::generate_enum(t_enum* tenum) { indent_up(); generate_delphi_doc(s_enum, tenum); indent(s_enum) << type_name(tenum, true, true) << " = " - << "(" << endl; + << "(" << '\n'; indent_up(); vector constants = tenum->get_constants(); if (constants.empty()) { @@ -969,16 +924,19 @@ void t_delphi_generator::generate_enum(t_enum* tenum) { int value = (*c_iter)->get_value(); if (c_iter != constants.begin()) { s_enum << ","; - s_enum << endl; + s_enum << '\n'; } generate_delphi_doc(s_enum, *c_iter); indent(s_enum) << normalize_name((*c_iter)->get_name()) << " = " << value; + s_enum << render_deprecation_attribute((*c_iter)->annotations_, " {", "}"); } } - s_enum << endl; + s_enum << '\n'; indent_down(); - indent(s_enum) << ");" << endl << endl; + indent(s_enum) << ")" << render_deprecation_attribute(tenum->annotations_, " ", "") << ";" << '\n' << '\n'; indent_down(); + + add_defined_type(tenum); } std::string t_delphi_generator::make_pascal_string_literal(std::string value) { @@ -991,7 +949,7 @@ std::string t_delphi_generator::make_pascal_string_literal(std::string value) { result << "'"; for (signed char const c: value) { if( (c >= 0) && (c < 32)) { // convert ctrl chars, but leave UTF-8 alone - result << "#" << (int)c; + result << "#" << (int)c; } else if (c == '\'') { result << "''"; // duplicate any single quotes we find } else { @@ -999,7 +957,7 @@ std::string t_delphi_generator::make_pascal_string_literal(std::string value) { } } result << "'"; - + return result.str(); } @@ -1047,8 +1005,8 @@ void t_delphi_generator::generate_consts(std::vector consts) { string constants_class = make_constants_classname(); indent_up(); - indent(s_const) << constants_class.c_str() << " = class" << endl; - indent(s_const) << "private" << endl; + indent(s_const) << constants_class.c_str() << " = class" << '\n'; + indent(s_const) << "private" << '\n'; indent_up(); vector::iterator c_iter; for (c_iter = consts.begin(); c_iter != consts.end(); ++c_iter) { @@ -1060,7 +1018,7 @@ void t_delphi_generator::generate_consts(std::vector consts) { } } indent_down(); - indent(s_const) << "public" << endl; + indent(s_const) << "public" << '\n'; indent_up(); for (c_iter = consts.begin(); c_iter != consts.end(); ++c_iter) { generate_delphi_doc(s_const, *c_iter); @@ -1069,12 +1027,12 @@ void t_delphi_generator::generate_consts(std::vector consts) { (*c_iter)->get_type(), (*c_iter)->get_value()); } - indent(s_const) << "{$IF CompilerVersion >= 21.0}" << endl; - indent(s_const) << "class constructor Create;" << endl; - indent(s_const) << "class destructor Destroy;" << endl; - indent(s_const) << "{$IFEND}" << endl; + indent(s_const) << "{$IF CompilerVersion >= 21.0}" << '\n'; + indent(s_const) << "class constructor Create;" << '\n'; + indent(s_const) << "class destructor Destroy;" << '\n'; + indent(s_const) << "{$IFEND}" << '\n'; indent_down(); - indent(s_const) << "end;" << endl << endl; + indent(s_const) << "end;" << '\n' << '\n'; indent_down(); std::ostringstream vars, code; @@ -1085,26 +1043,27 @@ void t_delphi_generator::generate_consts(std::vector consts) { code, prop_name((*c_iter)->get_name(), false, "F"), (*c_iter)->get_type(), - (*c_iter)->get_value()); + (*c_iter)->get_value(), + true); } indent_down_impl(); - indent_impl(s_const_impl) << "{$IF CompilerVersion >= 21.0}" << endl; + indent_impl(s_const_impl) << "{$IF CompilerVersion >= 21.0}" << '\n'; indent_impl(s_const_impl) << "class constructor " << constants_class.c_str() << ".Create;" - << endl; + << '\n'; if (!vars.str().empty()) { - indent_impl(s_const_impl) << "var" << endl; + indent_impl(s_const_impl) << "var" << '\n'; s_const_impl << vars.str(); } - indent_impl(s_const_impl) << "begin" << endl; + indent_impl(s_const_impl) << "begin" << '\n'; if (!code.str().empty()) { s_const_impl << code.str(); } - indent_impl(s_const_impl) << "end;" << endl << endl; + indent_impl(s_const_impl) << "end;" << '\n' << '\n'; indent_impl(s_const_impl) << "class destructor " << constants_class.c_str() << ".Destroy;" - << endl; - indent_impl(s_const_impl) << "begin" << endl; + << '\n'; + indent_impl(s_const_impl) << "begin" << '\n'; indent_up_impl(); for (c_iter = consts.begin(); c_iter != consts.end(); ++c_iter) { if (const_needs_var((*c_iter)->get_type())) { @@ -1114,10 +1073,10 @@ void t_delphi_generator::generate_consts(std::vector consts) { (*c_iter)->get_value()); } } - indent_impl(s_const_impl) << "inherited;" << endl; + indent_impl(s_const_impl) << "inherited;" << '\n'; indent_down_impl(); - indent_impl(s_const_impl) << "end;" << endl; - indent_impl(s_const_impl) << "{$ELSE}" << endl; + indent_impl(s_const_impl) << "end;" << '\n'; + indent_impl(s_const_impl) << "{$ELSE}" << '\n'; vars.str(""); code.str(""); @@ -1129,24 +1088,25 @@ void t_delphi_generator::generate_consts(std::vector consts) { code, constants_class + "." + prop_name((*c_iter)->get_name(), false, "F"), (*c_iter)->get_type(), - (*c_iter)->get_value()); + (*c_iter)->get_value(), + true); } } indent_down_impl(); - indent_impl(s_const_impl) << "procedure " << constants_class.c_str() << "_Initialize;" << endl; + indent_impl(s_const_impl) << "procedure " << constants_class.c_str() << "_Initialize;" << '\n'; if (!vars.str().empty()) { - indent_impl(s_const_impl) << "var" << endl; + indent_impl(s_const_impl) << "var" << '\n'; s_const_impl << vars.str(); } - indent_impl(s_const_impl) << "begin" << endl; + indent_impl(s_const_impl) << "begin" << '\n'; if (!code.str().empty()) { s_const_impl << code.str(); } - indent_impl(s_const_impl) << "end;" << endl << endl; + indent_impl(s_const_impl) << "end;" << '\n' << '\n'; - indent_impl(s_const_impl) << "procedure " << constants_class.c_str() << "_Finalize;" << endl; - indent_impl(s_const_impl) << "begin" << endl; + indent_impl(s_const_impl) << "procedure " << constants_class.c_str() << "_Finalize;" << '\n'; + indent_impl(s_const_impl) << "begin" << '\n'; indent_up_impl(); for (c_iter = consts.begin(); c_iter != consts.end(); ++c_iter) { finalize_field(s_const_impl, @@ -1156,8 +1116,8 @@ void t_delphi_generator::generate_consts(std::vector consts) { constants_class); } indent_down_impl(); - indent_impl(s_const_impl) << "end;" << endl; - indent_impl(s_const_impl) << "{$IFEND}" << endl << endl; + indent_impl(s_const_impl) << "end;" << '\n'; + indent_impl(s_const_impl) << "{$IFEND}" << '\n' << '\n'; } void t_delphi_generator::print_const_def_value(std::ostream& vars, @@ -1190,10 +1150,10 @@ void t_delphi_generator::print_const_def_value(std::ostream& vars, if (field_type == nullptr) { throw "type error: " + type->get_name() + " has no field " + v_iter->first->get_string(); } - string val = render_const_value(vars, out, name, field_type, v_iter->second); + string val = render_const_value(vars, out, field_type, v_iter->second, false); indent_impl(out) << cls_prefix << normalize_name(name) << "." << prop_name(v_iter->first->get_string(), type->is_xception()) - << " := " << val << ";" << endl; + << " := " << val << ";" << '\n'; } } else if (type->is_map()) { t_type* ktype = ((t_map*)type)->get_key_type(); @@ -1201,10 +1161,10 @@ void t_delphi_generator::print_const_def_value(std::ostream& vars, const map& val = value->get_map(); map::const_iterator v_iter; for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { - string key = render_const_value(vars, out, name, ktype, v_iter->first); - string val = render_const_value(vars, out, name, vtype, v_iter->second); + string key = render_const_value(vars, out, ktype, v_iter->first, false); + string val = render_const_value(vars, out, vtype, v_iter->second, false); indent_impl(out) << cls_prefix << normalize_name(name) << "[" << key << "]" - << " := " << val << ";" << endl; + << " := " << val << ";" << '\n'; } } else if (type->is_list() || type->is_set()) { t_type* etype; @@ -1217,8 +1177,8 @@ void t_delphi_generator::print_const_def_value(std::ostream& vars, const vector& val = value->get_list(); vector::const_iterator v_iter; for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { - string val = render_const_value(vars, out, name, etype, *v_iter); - indent_impl(out) << cls_prefix << normalize_name(name) << ".Add(" << val << ");" << endl; + string val = render_const_value(vars, out, etype, *v_iter, false); + indent_impl(out) << cls_prefix << normalize_name(name) << ".Add(" << val << ");" << '\n'; } } } @@ -1228,15 +1188,25 @@ void t_delphi_generator::print_private_field(std::ostream& out, t_type* type, t_const_value* value) { (void)value; - indent(out) << "class var F" << name << ": " << type_name(type) << ";" << endl; + indent(out) << "class var F" << name << ": " << type_name(type) << ";" << '\n'; } bool t_delphi_generator::const_needs_var(t_type* type) { - t_type* truetype = type; - while (truetype->is_typedef()) { - truetype = ((t_typedef*)truetype)->get_type(); + t_type* truetype = type->get_true_type(); + + if(!truetype->is_base_type()) { + return true; + } + + t_base_type::t_base tbase = ((t_base_type*)truetype)->get_base(); + switch (tbase) { + case t_base_type::TYPE_UUID: + return true; + case t_base_type::TYPE_STRING: + return truetype->is_binary(); + default: + return false; } - return (!truetype->is_base_type()); } void t_delphi_generator::print_const_prop(std::ostream& out, @@ -1246,11 +1216,11 @@ void t_delphi_generator::print_const_prop(std::ostream& out, (void)value; if (const_needs_var(type)) { indent(out) << "class property " << name << ": " << type_name(type) << " read F" << name << ";" - << endl; + << '\n'; } else { std::ostringstream vars; // dummy - string v2 = render_const_value(vars, out, name, type, value); - indent(out) << "const " << name << " = " << v2 << ";" << endl; + string v2 = render_const_value(vars, out, type, value, true); + indent(out) << "const " << name << " = " << v2 << ";" << '\n'; } } @@ -1258,23 +1228,21 @@ void t_delphi_generator::print_const_value(std::ostream& vars, std::ostream& out, string name, t_type* type, - t_const_value* value) { - t_type* truetype = type; - while (truetype->is_typedef()) { - truetype = ((t_typedef*)truetype)->get_type(); - } + t_const_value* value, + bool is_const_class) { + t_type* truetype = type->get_true_type(); if (truetype->is_base_type()) { - // already done - // string v2 = render_const_value( vars, out, name, type, value); - // indent_impl(out) << name << " := " << v2 << ";" << endl; + if(const_needs_var(type) || (!is_const_class)) { + string the_value = render_const_value( vars, out, type, value, false); + indent_impl(out) << name << " := " << the_value << ";" << '\n'; + } } else if (truetype->is_enum()) { indent_impl(out) << name << " := " << type_name(type) << "." << value->get_identifier_name() - << ";" << endl; + << ";" << '\n'; } else { - string typname; - typname = type_name(truetype, true, false, type->is_xception(), type->is_xception()); - indent_impl(out) << name << " := " << typname << ".Create;" << endl; + string typname = type_name(truetype, true, false/*, type->is_xception(), type->is_xception()*/); + indent_impl(out) << name << " := " << typname << ".Create;" << '\n'; print_const_def_value(vars, out, name, truetype, value); } } @@ -1283,8 +1251,9 @@ void t_delphi_generator::initialize_field(std::ostream& vars, std::ostream& out, string name, t_type* type, - t_const_value* value) { - print_const_value(vars, out, name, type, value); + t_const_value* value, + bool is_const_class) { + print_const_value(vars, out, name, type, value, is_const_class); } void t_delphi_generator::finalize_field(std::ostream& out, @@ -1301,15 +1270,10 @@ void t_delphi_generator::finalize_field(std::ostream& out, string t_delphi_generator::render_const_value(ostream& vars, ostream& out, - string name, t_type* type, - t_const_value* value) { - (void)name; - - t_type* truetype = type; - while (truetype->is_typedef()) { - truetype = ((t_typedef*)truetype)->get_type(); - } + t_const_value* value, + bool guidAsLiteral) { + t_type* truetype = type->get_true_type(); std::ostringstream render; @@ -1317,10 +1281,18 @@ string t_delphi_generator::render_const_value(ostream& vars, t_base_type::t_base tbase = ((t_base_type*)truetype)->get_base(); switch (tbase) { case t_base_type::TYPE_STRING: - render << "'" << get_escaped_string(value) << "'"; + if (truetype->is_binary()) { + render << "TEncoding.UTF8.GetBytes('" << get_escaped_string(value) << "')"; + } else { + render << "'" << get_escaped_string(value) << "'"; + } break; case t_base_type::TYPE_UUID: - render << "['{" << value->get_uuid() << "}']"; + if(guidAsLiteral) { + render << "['{" << value->get_uuid() << "}']"; + } else { + render << "StringToGUID('{" << value->get_uuid() << "}')"; + } break; case t_base_type::TYPE_BOOL: render << ((value->get_integer() > 0) ? "True" : "False"); @@ -1351,8 +1323,8 @@ string t_delphi_generator::render_const_value(ostream& vars, render << type_name(type, false) << "." << value->get_identifier_name(); } else { string t = tmp("tmp"); - vars << " " << t << " : " << type_name(type) << ";" << endl; - print_const_value(vars, out, t, type, value); + vars << " " << t << " : " << type_name(type) << ";" << '\n'; + print_const_value(vars, out, t, type, value, true); render << t; } @@ -1360,54 +1332,54 @@ string t_delphi_generator::render_const_value(ostream& vars, } void t_delphi_generator::generate_struct(t_struct* tstruct) { - generate_delphi_struct(tstruct, false); + generate_delphi_struct(tstruct); } void t_delphi_generator::generate_xception(t_struct* txception) { - generate_delphi_struct(txception, true); + generate_delphi_exception(txception); } -void t_delphi_generator::generate_delphi_struct(t_struct* tstruct, bool is_exception) { +void t_delphi_generator::generate_delphi_struct(t_struct* tstruct) { indent_up(); - generate_delphi_struct_definition(s_struct, tstruct, is_exception); + generate_delphi_struct_definition(s_struct, tstruct); indent_down(); add_defined_type(tstruct); - generate_delphi_struct_impl(s_struct_impl, "", tstruct, is_exception); + generate_delphi_struct_impl(s_struct_impl, "", tstruct, false, false/*?*/); if (register_types_) { - generate_delphi_struct_type_factory(s_type_factory_funcs, "", tstruct, is_exception); - generate_delphi_struct_type_factory_registration(s_type_factory_registration, - "", - tstruct, - is_exception); + generate_delphi_struct_type_factory(s_type_factory_funcs, "", tstruct); + generate_delphi_struct_type_factory_registration(s_type_factory_registration, "", tstruct); } } -void t_delphi_generator::generate_delphi_struct_impl(ostream& out, - string cls_prefix, - t_struct* tstruct, - bool is_exception, - bool is_result, - bool is_x_factory) { - - if (is_exception && (!is_x_factory)) { - generate_delphi_struct_impl(out, cls_prefix, tstruct, is_exception, is_result, true); - } +void t_delphi_generator::generate_delphi_exception(t_struct* tstruct) { + // generate exception data class first + generate_delphi_struct(tstruct); - string cls_nm; + indent_up(); + generate_delphi_exception_definition(s_struct, tstruct); + indent_down(); - string exception_factory_name; + add_defined_type(tstruct); - if (is_exception) { - exception_factory_name = normalize_clsnm(tstruct->get_name(), "", true) + "Factory"; + generate_delphi_exception_impl(s_struct_impl, "", tstruct); + /* + if (register_types_) { + generate_delphi_exception_type_factory(s_type_factory_funcs, "", tstruct); + generate_delphi_exception_type_factory_registration(s_type_factory_registration, "", tstruct); } + */ +} - if (is_exception) { - cls_nm = type_name(tstruct, true, (!is_x_factory), is_x_factory, true); - } else { - cls_nm = type_name(tstruct, true, false); - } +void t_delphi_generator::generate_delphi_struct_impl(ostream& out, + string cls_prefix, + t_struct* tstruct, + bool is_result, + bool is_const_class) { + (void)is_result; + + string cls_nm = type_name(tstruct, true, false); std::ostringstream vars, code; @@ -1416,123 +1388,58 @@ void t_delphi_generator::generate_delphi_struct_impl(ostream& out, indent_up_impl(); for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { - t_type* t = (*m_iter)->get_type(); - while (t->is_typedef()) { - t = ((t_typedef*)t)->get_type(); - } + t_type* truetype = (*m_iter)->get_type()->get_true_type(); if ((*m_iter)->get_value() != nullptr) { initialize_field(vars, code, - prop_name((*m_iter)->get_name(), is_exception, ""), - t, - (*m_iter)->get_value()); + prop_name((*m_iter)->get_name(), false, "F"), + truetype, + (*m_iter)->get_value(), + is_const_class); if ((*m_iter)->get_req() != t_field::T_REQUIRED) { - indent_impl(code) << prop_name((*m_iter), is_exception, "F__isset_") << " := True;" - << endl; + indent_impl(code) << prop_name((*m_iter), false, "F__isset_") << " := True;" << '\n'; } } } indent_down_impl(); - indent_impl(out) << "constructor " << cls_prefix << cls_nm << "." - << "Create;" << endl; + indent_impl(out) << "constructor " << cls_prefix << cls_nm << ".Create;" << '\n'; if (!vars.str().empty()) { - out << "var" << endl; + out << "var" << '\n'; out << vars.str(); } - indent_impl(out) << "begin" << endl; + indent_impl(out) << "begin" << '\n'; indent_up_impl(); - if (is_exception && (!is_x_factory)) { - indent_impl(out) << "inherited Create('');" << endl; - } else { - indent_impl(out) << "inherited;" << endl; - } + indent_impl(out) << "inherited;" << '\n'; if (!code.str().empty()) { out << code.str(); } indent_down_impl(); - indent_impl(out) << "end;" << endl << endl; + indent_impl(out) << "end;" << '\n' << '\n'; - if ((members.size() > 0) && is_exception && (!is_x_factory)) { - indent_impl(out) << "constructor " << cls_prefix << cls_nm << "." - << "Create(" << constructor_argument_list(tstruct, indent_impl()) << ");" - << endl; - indent_impl(out) << "begin" << endl; - indent_up_impl(); - indent_impl(out) << "Create;" << endl; - for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { - string propname = prop_name((*m_iter)->get_name(), is_exception); - string param_name = constructor_param_name((*m_iter)->get_name()); - indent_impl(out) << propname << " := " << param_name << ";" << endl; - } - indent_impl(out) << "UpdateMessageProperty;" << endl; - indent_down_impl(); - indent_impl(out) << "end;" << endl << endl; - } - - indent_impl(out) << "destructor " << cls_prefix << cls_nm << "." - << "Destroy;" << endl; - indent_impl(out) << "begin" << endl; + indent_impl(out) << "destructor " << cls_prefix << cls_nm << ".Destroy;" << '\n'; + indent_impl(out) << "begin" << '\n'; indent_up_impl(); for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { - t_type* t = (*m_iter)->get_type(); - while (t->is_typedef()) { - t = ((t_typedef*)t)->get_type(); - } - finalize_field(out, prop_name(*m_iter, is_exception), t, (*m_iter)->get_value()); + t_type* t = (*m_iter)->get_type()->get_true_type(); + finalize_field(out, prop_name(*m_iter, false), t, (*m_iter)->get_value()); } - indent_impl(out) << "inherited;" << endl; + indent_impl(out) << "inherited;" << '\n'; indent_down_impl(); - indent_impl(out) << "end;" << endl << endl; - - if (is_exception && (!is_x_factory)) { - indent_impl(out) << "function " << cls_prefix << cls_nm << "." << exception_factory_name - << ": I" << exception_factory_name << ";" << endl; - indent_impl(out) << "begin" << endl; - indent_up_impl(); - indent_impl(out) << "if F" << exception_factory_name << " = nil" << endl; - indent_impl(out) << "then F" << exception_factory_name << " := T" << exception_factory_name << "Impl.Create;" << endl << endl; - indent_impl(out) << "result := F" << exception_factory_name << ";" << endl; - indent_down_impl(); - indent_impl(out) << "end;" << endl << endl; - indent_impl(out) << "function " << cls_prefix << cls_nm << ".QueryInterface(const IID: TGUID; out Obj): HRESULT;" << endl; - indent_impl(out) << "begin" << endl; - indent_up_impl(); - indent_impl(out) << "if GetInterface(IID, Obj)" << endl; - indent_impl(out) << "then result := S_OK" << endl; - indent_impl(out) << "else result := E_NOINTERFACE;" << endl; - indent_down_impl(); - indent_impl(out) << "end;" << endl << endl; - indent_impl(out) << "function " << cls_prefix << cls_nm << "._AddRef: Integer;" << endl; - indent_impl(out) << "begin" << endl; - indent_up_impl(); - indent_impl(out) << "result := -1; // not refcounted" << endl; - indent_down_impl(); - indent_impl(out) << "end;" << endl << endl; - indent_impl(out) << "function " << cls_prefix << cls_nm << "._Release: Integer;" << endl; - indent_impl(out) << "begin" << endl; - indent_up_impl(); - indent_impl(out) << "result := -1; // not refcounted" << endl; - indent_down_impl(); - indent_impl(out) << "end;" << endl << endl; - } + indent_impl(out) << "end;" << '\n' << '\n'; if (tstruct->is_union()) { - indent_impl(out) << "procedure " << cls_prefix << cls_nm << "." - << "ClearUnionValues;" << endl; - indent_impl(out) << "begin" << endl; + indent_impl(out) << "procedure " << cls_prefix << cls_nm << ".ClearUnionValues;" << '\n'; + indent_impl(out) << "begin" << '\n'; indent_up_impl(); for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { - t_type* t = (*m_iter)->get_type(); - while (t->is_typedef()) { - t = ((t_typedef*)t)->get_type(); - } + t_type* t = (*m_iter)->get_type()->get_true_type(); generate_delphi_clear_union_value(out, cls_prefix, @@ -1540,47 +1447,136 @@ void t_delphi_generator::generate_delphi_struct_impl(ostream& out, t, *m_iter, "F", - is_exception, - tstruct->is_union(), - is_x_factory, - exception_factory_name); + false, + tstruct->is_union()); } indent_down_impl(); - indent_impl(out) << "end;" << endl << endl; + indent_impl(out) << "end;" << '\n' << '\n'; } for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { - t_type* t = (*m_iter)->get_type(); - while (t->is_typedef()) { - t = ((t_typedef*)t)->get_type(); - } - generate_delphi_property_reader_impl(out, cls_prefix, cls_nm, t, *m_iter, "F", is_exception); + t_type* t = (*m_iter)->get_type()->get_true_type(); + generate_delphi_property_reader_impl(out, cls_prefix, cls_nm, t, *m_iter, "F", false); generate_delphi_property_writer_impl(out, cls_prefix, cls_nm, t, *m_iter, "F", - is_exception, - tstruct->is_union(), - is_x_factory, - exception_factory_name); + false, + tstruct->is_union()); if ((*m_iter)->get_req() != t_field::T_REQUIRED) { - generate_delphi_isset_reader_writer_impl(out, cls_prefix, cls_nm, t, *m_iter, "F", is_exception); + generate_delphi_isset_reader_writer_impl(out, cls_prefix, cls_nm, t, *m_iter, "F", false); } } - generate_delphi_struct_reader_impl(out, cls_prefix, tstruct, is_exception, is_x_factory); - if (is_result) { - generate_delphi_struct_result_writer_impl(out, cls_prefix, tstruct, is_exception, is_x_factory); - } else { - generate_delphi_struct_writer_impl(out, cls_prefix, tstruct, is_exception, is_x_factory); + generate_delphi_struct_reader_impl(out, cls_prefix, tstruct, false); + generate_delphi_struct_writer_impl(out, cls_prefix, tstruct, false); + generate_delphi_struct_tostring_impl(out, cls_prefix, tstruct, false); +} + +void t_delphi_generator::generate_delphi_exception_impl(ostream& out, + string cls_prefix, + t_struct* tstruct) { + + string cls_nm = type_name(tstruct, true, true/*, false, true*/); + + const vector& members = tstruct->get_members(); + vector::const_iterator m_iter; + + indent_impl(out) << "constructor " << cls_prefix << cls_nm << ".Create;" << '\n'; + indent_impl(out) << "begin" << '\n'; + indent_up_impl(); + indent_impl(out) << "inherited Create('');" << '\n'; + indent_impl(out) << "FData := " << type_name(tstruct, true, false) << ".Create;" << '\n'; + indent_down_impl(); + indent_impl(out) << "end;" << '\n' << '\n'; + + if (members.size() > 0) { + indent_impl(out) << "constructor " << cls_prefix << cls_nm << "." + << "Create(" << constructor_argument_list(tstruct, indent_impl()) << ");" + << '\n'; + indent_impl(out) << "begin" << '\n'; + indent_up_impl(); + indent_impl(out) << "Create;" << '\n'; + for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { + string propname = prop_name((*m_iter)->get_name(), true); + string param_name = constructor_param_name((*m_iter)->get_name()); + indent_impl(out) << propname << " := " << param_name << ";" << '\n'; + } + indent_impl(out) << "UpdateMessageProperty;" << '\n'; + indent_down_impl(); + indent_impl(out) << "end;" << '\n' << '\n'; + } + + indent_impl(out) << "constructor " << cls_prefix << cls_nm << "." + << "Create(const aData: " << type_name(tstruct, false, false) << ");" + << '\n'; + indent_impl(out) << "begin" << '\n'; + indent_up_impl(); + indent_impl(out) << "inherited Create('');" << '\n'; + indent_impl(out) << "if aData <> nil" << '\n'; + indent_impl(out) << "then FData := aData" << '\n'; + indent_impl(out) << "else ASSERT(FALSE,'Invalid argument');" << '\n'; + indent_impl(out) << "UpdateMessageProperty;" << '\n'; + indent_down_impl(); + indent_impl(out) << "end;" << '\n' << '\n'; + + indent_impl(out) << "destructor " << cls_prefix << cls_nm << "." + << "Destroy;" << '\n'; + indent_impl(out) << "begin" << '\n'; + indent_up_impl(); + + for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { + t_type* t = (*m_iter)->get_type()->get_true_type(); + finalize_field(out, prop_name(*m_iter, true), t, (*m_iter)->get_value()); } - generate_delphi_struct_tostring_impl(out, cls_prefix, tstruct, is_exception, is_x_factory); - if (is_exception && is_x_factory) { - generate_delphi_create_exception_impl(out, cls_prefix, tstruct, is_exception); + indent_impl(out) << "inherited;" << '\n'; + indent_down_impl(); + indent_impl(out) << "end;" << '\n' << '\n'; + + // non-refcounted IUnknown impl + indent_impl(out) << "function " << cls_prefix << cls_nm << ".QueryInterface(const IID: TGUID; out Obj): HRESULT;" << '\n'; + indent_impl(out) << "begin" << '\n'; + indent_up_impl(); + indent_impl(out) << "if GetInterface(IID, Obj)" << '\n'; + indent_impl(out) << "then result := S_OK" << '\n'; + indent_impl(out) << "else result := E_NOINTERFACE;" << '\n'; + indent_down_impl(); + indent_impl(out) << "end;" << '\n' << '\n'; + indent_impl(out) << "function " << cls_prefix << cls_nm << "._AddRef: Integer;" << '\n'; + indent_impl(out) << "begin" << '\n'; + indent_up_impl(); + indent_impl(out) << "result := -1; // not refcounted" << '\n'; + indent_down_impl(); + indent_impl(out) << "end;" << '\n' << '\n'; + indent_impl(out) << "function " << cls_prefix << cls_nm << "._Release: Integer;" << '\n'; + indent_impl(out) << "begin" << '\n'; + indent_up_impl(); + indent_impl(out) << "result := -1; // not refcounted" << '\n'; + indent_down_impl(); + indent_impl(out) << "end;" << '\n' << '\n'; + + for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { + t_type* t = (*m_iter)->get_type()->get_true_type(); + generate_delphi_property_reader_impl(out, cls_prefix, cls_nm, t, *m_iter, "", true); + generate_delphi_property_writer_impl(out, + cls_prefix, + cls_nm, + t, + *m_iter, + "", + true, + tstruct->is_union()); + if ((*m_iter)->get_req() != t_field::T_REQUIRED) { + generate_delphi_isset_reader_writer_impl(out, cls_prefix, cls_nm, t, *m_iter, "", true); + } } + + generate_delphi_struct_reader_impl(out, cls_prefix, tstruct, true); + generate_delphi_struct_writer_impl(out, cls_prefix, tstruct, true); + generate_delphi_struct_tostring_impl(out, cls_prefix, tstruct, true); } void t_delphi_generator::print_delphi_struct_type_factory_func(ostream& out, t_struct* tstruct) { @@ -1592,17 +1588,8 @@ void t_delphi_generator::print_delphi_struct_type_factory_func(ostream& out, t_s void t_delphi_generator::generate_delphi_struct_type_factory(ostream& out, string cls_prefix, - t_struct* tstruct, - bool is_exception, - bool is_result, - bool is_x_factory) { + t_struct* tstruct) { (void)cls_prefix; - if (is_exception) - return; - if (is_result) - return; - if (is_x_factory) - return; string struct_intf_name = type_name(tstruct); string cls_nm = type_name(tstruct, true, false); @@ -1611,42 +1598,29 @@ void t_delphi_generator::generate_delphi_struct_type_factory(ostream& out, print_delphi_struct_type_factory_func(out, tstruct); out << ": "; out << struct_intf_name; - out << ";" << endl; - out << "begin" << endl; + out << ";" << '\n'; + out << "begin" << '\n'; indent_up(); - indent(out) << "Result := " << cls_nm << ".Create;" << endl; + indent(out) << "Result := " << cls_nm << ".Create;" << '\n'; indent_down(); - out << "end;" << endl << endl; + out << "end;" << '\n' << '\n'; } void t_delphi_generator::generate_delphi_struct_type_factory_registration(ostream& out, string cls_prefix, - t_struct* tstruct, - bool is_exception, - bool is_result, - bool is_x_factory) { + t_struct* tstruct) { (void)cls_prefix; - if (is_exception) - return; - if (is_result) - return; - if (is_x_factory) - return; string struct_intf_name = type_name(tstruct); indent(out) << " TypeRegistry.RegisterTypeFactory<" << struct_intf_name << ">("; print_delphi_struct_type_factory_func(out, tstruct); out << ");"; - out << endl; + out << '\n'; } -void t_delphi_generator::generate_delphi_struct_definition(ostream& out, - t_struct* tstruct, - bool is_exception, - bool in_class, - bool is_result, - bool is_x_factory) { +void t_delphi_generator::generate_delphi_struct_definition(ostream& out, + t_struct* tstruct) { bool is_final = (tstruct->annotations_.find("final") != tstruct->annotations_.end()); string struct_intf_name; string struct_name; @@ -1654,232 +1628,252 @@ void t_delphi_generator::generate_delphi_struct_definition(ostream& out, const vector& members = tstruct->get_members(); vector::const_iterator m_iter; - string exception_factory_name = normalize_clsnm(tstruct->get_name(), "", true) + "Factory"; - - if (is_exception) { - struct_intf_name = type_name(tstruct, false, false, true); - } else { - struct_intf_name = type_name(tstruct); - } + struct_intf_name = type_name(tstruct, false, false); + struct_name = type_name(tstruct, true); - if (is_exception) { - struct_name = type_name(tstruct, true, (!is_x_factory), is_x_factory); + generate_delphi_doc(out, tstruct); + if(rtti_) { + indent(out) << "{$TYPEINFO ON}" << '\n'; + indent(out) << "{$RTTI EXPLICIT METHODS([vcPublic, vcPublished]) PROPERTIES([vcPublic, vcPublished])}" << '\n'; + indent(out) << struct_intf_name << " = interface(IBaseWithTypeInfo)" << '\n'; } else { - struct_name = type_name(tstruct, true); + indent(out) << struct_intf_name << " = interface(IBase)" << '\n'; } + indent_up(); - if ((!is_exception) || is_x_factory) { - - generate_delphi_doc(out, tstruct); - if(rtti_) { - indent(out) << "{$TYPEINFO ON}" << endl; - indent(out) << "{$RTTI EXPLICIT METHODS([vcPublic, vcPublished]) PROPERTIES([vcPublic, vcPublished])}" << endl; - indent(out) << struct_intf_name << " = interface(IBaseWithTypeInfo)" << endl; - } else { - indent(out) << struct_intf_name << " = interface(IBase)" << endl; - } - indent_up(); + generate_guid(out); - generate_guid(out); + for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { + generate_delphi_property_reader_definition(out, *m_iter, false); + generate_delphi_property_writer_definition(out, *m_iter, false); + } + if (members.size() > 0) { + out << '\n'; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { - generate_delphi_property_reader_definition(out, *m_iter, is_exception); - generate_delphi_property_writer_definition(out, *m_iter, is_exception); - } - - if (is_x_factory) { - out << endl; - indent(out) << "// Create Exception Object" << endl; - indent(out) << "function CreateException: " << type_name(tstruct, true, true) << ";" << endl; + generate_property(out, *m_iter, true, false); } - if (members.size() > 0) { - out << endl; - for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { - generate_property(out, *m_iter, true, is_exception); - } - } - - if (members.size() > 0) { - out << endl; - for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { - if ((*m_iter)->get_req() != t_field::T_REQUIRED) { - generate_delphi_isset_reader_writer_definition(out, *m_iter, is_exception); - } + out << '\n'; + for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { + if ((*m_iter)->get_req() != t_field::T_REQUIRED) { + generate_delphi_isset_reader_writer_definition(out, *m_iter, false); } } - if (members.size() > 0) { - out << endl; - for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { - if ((*m_iter)->get_req() != t_field::T_REQUIRED) { - isset_name = prop_name(*m_iter, is_exception, "__isset_"); - indent(out) << "property " << isset_name << ": System.Boolean read Get" << isset_name << " write Set" << isset_name << ";" - << endl; - } + out << '\n'; + for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { + if ((*m_iter)->get_req() != t_field::T_REQUIRED) { + isset_name = prop_name(*m_iter, false, "__isset_"); + indent(out) << "property " << isset_name << ": System.Boolean read Get" << isset_name << " write Set" << isset_name << ";" + << '\n'; } } + } - indent_down(); - indent(out) << "end;" << endl; - if(rtti_) { - indent(out) << "{$IFNDEF TYPEINFO_WAS_ON} {$TYPEINFO OFF} {$ENDIF}" << endl; - } - indent(out) << endl; + indent_down(); + indent(out) << "end;" + << render_deprecation_attribute(tstruct->annotations_, " {", "}") + << '\n'; + if(rtti_) { + indent(out) << "{$IFNDEF TYPEINFO_WAS_ON} {$TYPEINFO OFF} {$ENDIF}" << '\n'; } + indent(out) << '\n'; generate_delphi_doc(out, tstruct); indent(out) << struct_name << " = "; if (is_final) { out << "sealed "; } - out << "class("; - if (is_exception && (!is_x_factory)) { - out << "TException, IInterface, IBase, ISupportsToString"; - } else { - out << "TInterfacedObject, IBase, ISupportsToString, " << struct_intf_name; - } - out << ")" << endl; + out << "class(TInterfacedObject, IBase, ISupportsToString, " << struct_intf_name << ")" << '\n'; - if (is_exception && (!is_x_factory)) { - indent(out) << "public" << endl; - indent_up(); - indent(out) << "type" << endl; - indent_up(); - generate_delphi_struct_definition(out, tstruct, is_exception, in_class, is_result, true); - indent_down(); - indent_down(); - } - - indent(out) << "private" << endl; + indent(out) << "private" << '\n'; indent_up(); - if (is_exception && (!is_x_factory)) { - indent(out) << "F" << exception_factory_name << " :" << struct_intf_name << ";" << endl << endl; - } - for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { - indent(out) << declare_field(*m_iter, false, "F", is_exception) << endl; + indent(out) << declare_field(*m_iter, "F", false) << '\n'; } if (members.size() > 0) { - indent(out) << endl; + indent(out) << '\n'; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { if ((*m_iter)->get_req() != t_field::T_REQUIRED) { - isset_name = prop_name(*m_iter, is_exception, "F__isset_"); - indent(out) << isset_name << ": System.Boolean;" << endl; + isset_name = prop_name(*m_iter, false, "F__isset_"); + indent(out) << isset_name << ": System.Boolean;" << '\n'; } } } - indent(out) << endl; + indent(out) << '\n'; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { - generate_delphi_property_reader_definition(out, *m_iter, is_exception); - generate_delphi_property_writer_definition(out, *m_iter, is_exception); + generate_delphi_property_reader_definition(out, *m_iter, false); + generate_delphi_property_writer_definition(out, *m_iter, false); } if (tstruct->is_union()) { - out << endl; - indent(out) << "// Clear values(for union's property setter)" << endl; - indent(out) << "procedure ClearUnionValues;" << endl; + out << '\n'; + indent(out) << "// Clear values(for union's property setter)" << '\n'; + indent(out) << "procedure ClearUnionValues;" << '\n'; } if (members.size() > 0) { - out << endl; + out << '\n'; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { if ((*m_iter)->get_req() != t_field::T_REQUIRED) { - isset_name = prop_name(*m_iter, is_exception, "__isset_"); - indent(out) << "function Get" << isset_name << ": System.Boolean;" << endl; - indent(out) << "procedure Set" << isset_name << "( const value : System.Boolean);" << endl; + isset_name = prop_name(*m_iter, false, "__isset_"); + indent(out) << "function Get" << isset_name << ": System.Boolean;" << '\n'; + indent(out) << "procedure Set" << isset_name << "( const value : System.Boolean);" << '\n'; } } } - if (is_exception && (!is_x_factory)) { - out << endl; - indent_down(); - indent(out) << "strict protected" << endl; - indent_up(); - indent(out) << "function QueryInterface(const IID: TGUID; out Obj): HRESULT; stdcall;" << endl; - indent(out) << "function _AddRef: Integer; stdcall;" << endl; - indent(out) << "function _Release: Integer; stdcall;" << endl; - out << endl; - } - indent_down(); - indent(out) << "public" << endl; + indent(out) << "public" << '\n'; indent_up(); + indent(out) << "constructor Create;" << render_deprecation_attribute(tstruct->annotations_," ",";") << '\n'; + indent(out) << "destructor Destroy; override;" << '\n'; - if ((members.size() > 0) && is_exception && (!is_x_factory)) { - indent(out) << "constructor Create; overload;" << endl; - indent(out) << "constructor Create(" << constructor_argument_list(tstruct, indent()) - << "); overload;" << endl; - } else { - indent(out) << "constructor Create;" << endl; + out << '\n'; + indent(out) << "function ToString: string; override;" << '\n'; + + out << '\n'; + indent(out) << "// IBase" << '\n'; + indent(out) << "procedure Read( const iprot: IProtocol);" << '\n'; + indent(out) << "procedure Write( const oprot: IProtocol);" << '\n'; + + if (members.size() > 0) { + out << '\n'; + indent(out) << "// Properties" << '\n'; + for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { + generate_property(out, *m_iter, true, false); + } + + out << '\n'; + indent(out) << "// isset" << '\n'; + for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { + if ((*m_iter)->get_req() != t_field::T_REQUIRED) { + isset_name = prop_name(*m_iter, false, "__isset_"); + indent(out) << "property " << isset_name << ": System.Boolean read Get" << isset_name << " write Set" << isset_name << ";" + << '\n'; + } + } } - indent(out) << "destructor Destroy; override;" << endl; + indent_down(); + indent(out) << "end;" << '\n' << '\n'; +} + +void t_delphi_generator::generate_delphi_exception_definition(ostream& out, + t_struct* tstruct) { + bool is_final = (tstruct->annotations_.find("final") != tstruct->annotations_.end()); + string struct_intf_name; + string struct_name; + string isset_name; + const vector& members = tstruct->get_members(); + vector::const_iterator m_iter; - out << endl; - indent(out) << "function ToString: string; override;" << endl; + struct_intf_name = type_name(tstruct, false, false); + struct_name = type_name(tstruct, true, true); - if (is_exception && (!is_x_factory)) { - out << endl; - indent(out) << "// Exception Factory" << endl; - indent(out) << "function " << exception_factory_name << ": " << struct_intf_name << ";" << endl; + generate_delphi_doc(out, tstruct); + indent(out) << struct_name << " = "; + if (is_final) { + out << "sealed "; } + out << "class(TException, IInterface, IBase, ISupportsToString)" << '\n'; - out << endl; - indent(out) << "// IBase" << endl; - indent(out) << "procedure Read( const iprot: IProtocol);" << endl; - indent(out) << "procedure Write( const oprot: IProtocol);" << endl; + indent(out) << "private" << '\n'; + indent_up(); + indent(out) << "FData : " << struct_intf_name << ';' << '\n'; + indent(out) << '\n'; - if (is_exception && is_x_factory) { - out << endl; - indent(out) << "// Create Exception Object" << endl; - indent(out) << "function CreateException: " << type_name(tstruct, true, true) << ";" << endl; + for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { + generate_delphi_property_reader_definition(out, *m_iter, true); + generate_delphi_property_writer_definition(out, *m_iter, true); } if (members.size() > 0) { - out << endl; - indent(out) << "// Properties" << endl; + out << '\n'; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { - generate_property(out, *m_iter, true, is_exception); + if ((*m_iter)->get_req() != t_field::T_REQUIRED) { + isset_name = prop_name(*m_iter, true, "__isset_"); + indent(out) << "function Get" << isset_name << ": System.Boolean;" << '\n'; + indent(out) << "procedure Set" << isset_name << "( const value : System.Boolean);" << '\n'; + } } } + out << '\n'; + indent_down(); + indent(out) << "strict protected" << '\n'; + indent_up(); + indent(out) << "// non-refcounted instance" << '\n'; + indent(out) << "function QueryInterface(const IID: TGUID; out Obj): HRESULT; stdcall;" << '\n'; + indent(out) << "function _AddRef: Integer; stdcall;" << '\n'; + indent(out) << "function _Release: Integer; stdcall;" << '\n'; + out << '\n'; + + indent_down(); + indent(out) << "public" << '\n'; + indent_up(); + + indent(out) << "constructor Create; overload;" << render_deprecation_attribute(tstruct->annotations_," ",";") << '\n'; + if (members.size() > 0) { + indent(out) << "constructor Create(" << constructor_argument_list(tstruct, indent()) + << "); overload;" << render_deprecation_attribute(tstruct->annotations_," ",";") << '\n'; + } + indent(out) << "constructor Create( const aData: " << struct_intf_name + << "); overload;" << render_deprecation_attribute(tstruct->annotations_," ",";") << '\n'; + + indent(out) << "destructor Destroy; override;" << '\n'; + + out << '\n'; + indent(out) << "property ExceptionData : " << struct_intf_name << " read FData;" << '\n'; + indent(out) << "function ToString: string; override;" << '\n'; + + out << '\n'; + indent(out) << "// IBase" << '\n'; + indent(out) << "procedure Read( const iprot: IProtocol);" << '\n'; + indent(out) << "procedure Write( const oprot: IProtocol);" << '\n'; + if (members.size() > 0) { - out << endl; - indent(out) << "// isset" << endl; + out << '\n'; + indent(out) << "// Properties" << '\n'; + for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { + generate_property(out, *m_iter, true, true); + } + + out << '\n'; + indent(out) << "// isset" << '\n'; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { if ((*m_iter)->get_req() != t_field::T_REQUIRED) { - isset_name = prop_name(*m_iter, is_exception, "__isset_"); + isset_name = prop_name(*m_iter, true, "__isset_"); indent(out) << "property " << isset_name << ": System.Boolean read Get" << isset_name << " write Set" << isset_name << ";" - << endl; + << '\n'; } } } indent_down(); - indent(out) << "end;" << endl << endl; + indent(out) << "end;" << '\n' << '\n'; } void t_delphi_generator::generate_service(t_service* tservice) { indent_up(); generate_delphi_doc(s_service, tservice); - indent(s_service) << normalize_clsnm(service_name_, "T") << " = class" << endl; - indent(s_service) << "public" << endl; + indent(s_service) << normalize_clsnm(service_name_, "T") << " = class" << '\n'; + indent(s_service) << "public" << '\n'; indent_up(); - indent(s_service) << "type" << endl; + indent(s_service) << "type" << '\n'; generate_service_interface(tservice); generate_service_client(tservice); generate_service_server(tservice); generate_service_helpers(tservice); indent_down(); indent_down(); - indent(s_service) << "end;" << endl; - indent(s_service) << endl; + indent(s_service) << "end;" << '\n'; + indent(s_service) << '\n'; indent_down(); } @@ -1903,9 +1897,9 @@ void t_delphi_generator::generate_service_interface(t_service* tservice, bool fo extends = type_name(tservice->get_extends(), true, true); extends_iface = extends + "." + iface_name; generate_delphi_doc(s_service, tservice); - indent(s_service) << iface_name << " = interface(" << extends_iface << ")" << endl; + indent(s_service) << iface_name << " = interface(" << extends_iface << ")" << '\n'; } else { - indent(s_service) << iface_name << " = interface" << endl; + indent(s_service) << iface_name << " = interface" << '\n'; } indent_up(); @@ -1914,10 +1908,12 @@ void t_delphi_generator::generate_service_interface(t_service* tservice, bool fo vector::iterator f_iter; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { generate_delphi_doc(s_service, *f_iter); - indent(s_service) << function_signature(*f_iter, for_async) << endl; + indent(s_service) << function_signature(*f_iter, for_async) << '\n'; } indent_down(); - indent(s_service) << "end;" << endl << endl; + indent(s_service) << "end;" + << render_deprecation_attribute( tservice->annotations_, " {", "}") + << '\n' << '\n'; indent_down(); } @@ -1931,7 +1927,7 @@ void t_delphi_generator::generate_guid(std::ostream& out) { std::wstring guid_wstr(guid_chars); std::wstring_convert> convert; std::string guid_str = convert.to_bytes(guid_wstr); - indent(out) << "['" << guid_str << "']" << endl; + indent(out) << "['" << guid_str << "']" << '\n'; } } #else @@ -1945,11 +1941,11 @@ void t_delphi_generator::generate_service_helpers(t_service* tservice) { for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { t_struct* ts = (*f_iter)->get_arglist(); - generate_delphi_struct_definition(s_service, ts, false, true); + generate_delphi_struct_definition(s_service, ts); generate_delphi_struct_impl(s_service_impl, normalize_clsnm(service_name_, "T") + ".", ts, - false); + false, false); generate_function_helpers(*f_iter); } } @@ -1965,78 +1961,78 @@ void t_delphi_generator::generate_service_client(t_service* tservice) { extends = type_name(tservice->get_extends(), true, true); extends_client = extends + ".TClient"; } - indent(s_service) << "TClient = class( " << extends_client << ", " << implements << ")" << endl; + indent(s_service) << "TClient = class( " << extends_client << ", " << implements << ")" << '\n'; - indent(s_service) << "public" << endl; + indent(s_service) << "public" << '\n'; indent_up(); - indent(s_service) << "constructor Create( prot: IProtocol); overload;" << endl; + indent(s_service) << "constructor Create( prot: IProtocol); overload;" << '\n'; indent_impl(s_service_impl) << "constructor " << normalize_clsnm(service_name_, "T") - << ".TClient.Create( prot: IProtocol);" << endl; - indent_impl(s_service_impl) << "begin" << endl; + << ".TClient.Create( prot: IProtocol);" << '\n'; + indent_impl(s_service_impl) << "begin" << '\n'; indent_up_impl(); - indent_impl(s_service_impl) << "Create( prot, prot );" << endl; + indent_impl(s_service_impl) << "Create( prot, prot );" << '\n'; indent_down_impl(); - indent_impl(s_service_impl) << "end;" << endl << endl; + indent_impl(s_service_impl) << "end;" << '\n' << '\n'; indent(s_service) - << "constructor Create( const iprot: IProtocol; const oprot: IProtocol); overload;" << endl; + << "constructor Create( const iprot: IProtocol; const oprot: IProtocol); overload;" << '\n'; indent_impl(s_service_impl) << "constructor " << normalize_clsnm(service_name_, "T") << ".TClient.Create( const iprot: IProtocol; const oprot: IProtocol);" - << endl; - indent_impl(s_service_impl) << "begin" << endl; + << '\n'; + indent_impl(s_service_impl) << "begin" << '\n'; indent_up_impl(); - indent_impl(s_service_impl) << "inherited Create;" << endl; - indent_impl(s_service_impl) << "iprot_ := iprot;" << endl; - indent_impl(s_service_impl) << "oprot_ := oprot;" << endl; + indent_impl(s_service_impl) << "inherited Create;" << '\n'; + indent_impl(s_service_impl) << "iprot_ := iprot;" << '\n'; + indent_impl(s_service_impl) << "oprot_ := oprot;" << '\n'; indent_down_impl(); - indent_impl(s_service_impl) << "end;" << endl << endl; + indent_impl(s_service_impl) << "end;" << '\n' << '\n'; indent_down(); if (extends.empty()) { - indent(s_service) << "protected" << endl; + indent(s_service) << "protected" << '\n'; indent_up(); - indent(s_service) << "iprot_: IProtocol;" << endl; - indent(s_service) << "oprot_: IProtocol;" << endl; - indent(s_service) << "seqid_: System.Integer;" << endl; + indent(s_service) << "iprot_: IProtocol;" << '\n'; + indent(s_service) << "oprot_: IProtocol;" << '\n'; + indent(s_service) << "seqid_: System.Integer;" << '\n'; indent_down(); - indent(s_service) << "public" << endl; + indent(s_service) << "public" << '\n'; indent_up(); - indent(s_service) << "property InputProtocol: IProtocol read iprot_;" << endl; - indent(s_service) << "property OutputProtocol: IProtocol read oprot_;" << endl; + indent(s_service) << "property InputProtocol: IProtocol read iprot_;" << '\n'; + indent(s_service) << "property OutputProtocol: IProtocol read oprot_;" << '\n'; indent_down(); } vector functions = tservice->get_functions(); vector::const_iterator f_iter; - indent(s_service) << "protected" << endl; + indent(s_service) << "protected" << '\n'; indent_up(); - indent(s_service) << "// Iface" << endl; + indent(s_service) << "// Iface" << '\n'; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { string funname = (*f_iter)->get_name(); generate_delphi_doc(s_service, *f_iter); - indent(s_service) << function_signature(*f_iter, false) << endl; + indent(s_service) << function_signature(*f_iter, false) << '\n'; } if( async_) { - indent(s_service) << endl; - indent(s_service) << "// IAsync" << endl; + indent(s_service) << '\n'; + indent(s_service) << "// IAsync" << '\n'; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { string funname = (*f_iter)->get_name(); generate_delphi_doc(s_service, *f_iter); - indent(s_service) << function_signature(*f_iter, true) << endl; + indent(s_service) << function_signature(*f_iter, true) << '\n'; } } indent_down(); - indent(s_service) << "public" << endl; + indent(s_service) << "public" << '\n'; indent_up(); string full_cls = normalize_clsnm(service_name_, "T") + ".TClient"; @@ -2054,20 +2050,20 @@ void t_delphi_generator::generate_service_client(t_service* tservice) { bool for_async = (mode != 0); mode--; - indent_impl(s_service_impl) << function_signature(*f_iter, for_async, full_cls) << endl; - indent_impl(s_service_impl) << "begin" << endl; + indent_impl(s_service_impl) << function_signature(*f_iter, for_async, full_cls) << '\n'; + indent_impl(s_service_impl) << "begin" << '\n'; indent_up_impl(); t_type* ttype = (*f_iter)->get_returntype(); if( for_async) { if (is_void(ttype)) { // Delphi forces us to specify a type with IFuture, so we use Integer=0 for void methods - indent_impl(s_service_impl) << "result := TTask.Future(function: System.Integer" << endl; + indent_impl(s_service_impl) << "result := TTask.Future(function: System.Integer" << '\n'; } else { - string rettype = type_name(ttype, false, true, false, true); - indent_impl(s_service_impl) << "result := TTask.Future<" << rettype << ">(function: " << rettype << endl; + string rettype = type_name(ttype, false, true/*, false, true*/); + indent_impl(s_service_impl) << "result := TTask.Future<" << rettype << ">(function: " << rettype << '\n'; } - indent_impl(s_service_impl) << "begin" << endl; + indent_impl(s_service_impl) << "begin" << '\n'; indent_up_impl(); } @@ -2082,26 +2078,26 @@ void t_delphi_generator::generate_service_client(t_service* tservice) { } s_service_impl << normalize_name((*fld_iter)->get_name()); } - s_service_impl << ");" << endl; + s_service_impl << ");" << '\n'; if (!(*f_iter)->is_oneway()) { s_service_impl << indent_impl(); if (!(*f_iter)->get_returntype()->is_void()) { s_service_impl << "Result := "; } - s_service_impl << "recv_" << funname << "();" << endl; + s_service_impl << "recv_" << funname << "();" << '\n'; } if( for_async) { if (is_void(ttype)) { - indent_impl(s_service_impl) << "Result := 0;" << endl; // no IFuture in Delphi + indent_impl(s_service_impl) << "Result := 0;" << '\n'; // no IFuture in Delphi } indent_down_impl(); - indent_impl(s_service_impl) << "end);" << endl; + indent_impl(s_service_impl) << "end);" << '\n'; } indent_down_impl(); - indent_impl(s_service_impl) << "end;" << endl << endl; + indent_impl(s_service_impl) << "end;" << '\n' << '\n'; } t_function send_function(g_type_void, @@ -2115,41 +2111,41 @@ void t_delphi_generator::generate_service_client(t_service* tservice) { string argsvar = tmp("_args"); string msgvar = tmp("_msg"); - indent(s_service) << function_signature(&send_function, false) << endl; - indent_impl(s_service_impl) << function_signature(&send_function, false, full_cls) << endl; - indent_impl(s_service_impl) << "var" << endl; + indent(s_service) << function_signature(&send_function, false) << '\n'; + indent_impl(s_service_impl) << function_signature(&send_function, false, full_cls) << '\n'; + indent_impl(s_service_impl) << "var" << '\n'; indent_up_impl(); - indent_impl(s_service_impl) << argsvar << " : " << args_intfnm << ";" << endl; - indent_impl(s_service_impl) << msgvar << " : Thrift.Protocol.TThriftMessage;" << endl; + indent_impl(s_service_impl) << argsvar << " : " << args_intfnm << ";" << '\n'; + indent_impl(s_service_impl) << msgvar << " : Thrift.Protocol.TThriftMessage;" << '\n'; indent_down_impl(); - indent_impl(s_service_impl) << "begin" << endl; + indent_impl(s_service_impl) << "begin" << '\n'; indent_up_impl(); - indent_impl(s_service_impl) << "seqid_ := seqid_ + 1;" << endl; + indent_impl(s_service_impl) << "seqid_ := seqid_ + 1;" << '\n'; indent_impl(s_service_impl) << "Thrift.Protocol.Init( " << msgvar << ", '" << funname << "', " << ((*f_iter)->is_oneway() ? "TMessageType.Oneway" : "TMessageType.Call") - << ", seqid_);" << endl; + << ", seqid_);" << '\n'; - indent_impl(s_service_impl) << "oprot_.WriteMessageBegin( " << msgvar << " );" << endl; - indent_impl(s_service_impl) << argsvar << " := " << args_clsnm << "Impl.Create();" << endl; + indent_impl(s_service_impl) << "oprot_.WriteMessageBegin( " << msgvar << " );" << '\n'; + indent_impl(s_service_impl) << argsvar << " := " << args_clsnm << "Impl.Create();" << '\n'; for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) { indent_impl(s_service_impl) << argsvar << "." << prop_name(*fld_iter) << " := " << normalize_name((*fld_iter)->get_name()) << ";" - << endl; + << '\n'; } - indent_impl(s_service_impl) << argsvar << ".Write(oprot_);" << endl; + indent_impl(s_service_impl) << argsvar << ".Write(oprot_);" << '\n'; for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) { indent_impl(s_service_impl) << argsvar << "." << prop_name(*fld_iter) - << " := " << empty_value((*fld_iter)->get_type()) << ";" << endl; + << " := " << empty_value((*fld_iter)->get_type()) << ";" << '\n'; } - indent_impl(s_service_impl) << "oprot_.WriteMessageEnd();" << endl; - indent_impl(s_service_impl) << "oprot_.Transport.Flush();" << endl; + indent_impl(s_service_impl) << "oprot_.WriteMessageEnd();" << '\n'; + indent_impl(s_service_impl) << "oprot_.Transport.Flush();" << '\n'; indent_down_impl(); - indent_impl(s_service_impl) << "end;" << endl << endl; + indent_impl(s_service_impl) << "end;" << '\n' << '\n'; if (!(*f_iter)->is_oneway()) { string org_resultname = (*f_iter)->get_name() + "_result"; @@ -2169,72 +2165,76 @@ void t_delphi_generator::generate_service_client(t_service* tservice) { string appexvar = tmp("_ax"); string retvar = tmp("_ret"); - indent(s_service) << function_signature(&recv_function, false) << endl; - indent_impl(s_service_impl) << function_signature(&recv_function, false, full_cls) << endl; - indent_impl(s_service_impl) << "var" << endl; + indent(s_service) << function_signature(&recv_function, false) << '\n'; + indent_impl(s_service_impl) << function_signature(&recv_function, false, full_cls) << '\n'; + indent_impl(s_service_impl) << "var" << '\n'; indent_up_impl(); - indent_impl(s_service_impl) << msgvar << " : Thrift.Protocol.TThriftMessage;" << endl; + indent_impl(s_service_impl) << msgvar << " : Thrift.Protocol.TThriftMessage;" << '\n'; if (xceptions.size() > 0) { - indent_impl(s_service_impl) << exceptvar << " : Exception;" << endl; + indent_impl(s_service_impl) << exceptvar << " : Exception;" << '\n'; } - indent_impl(s_service_impl) << appexvar << " : TApplicationException;" << endl; - indent_impl(s_service_impl) << retvar << " : " << result_intfnm << ";" << endl; + indent_impl(s_service_impl) << appexvar << " : TApplicationException;" << '\n'; + indent_impl(s_service_impl) << retvar << " : " << result_intfnm << ";" << '\n'; indent_down_impl(); - indent_impl(s_service_impl) << "begin" << endl; + indent_impl(s_service_impl) << "begin" << '\n'; indent_up_impl(); - indent_impl(s_service_impl) << msgvar << " := iprot_.ReadMessageBegin();" << endl; - indent_impl(s_service_impl) << "if (" << msgvar << ".Type_ = TMessageType.Exception) then begin" << endl; + indent_impl(s_service_impl) << msgvar << " := iprot_.ReadMessageBegin();" << '\n'; + indent_impl(s_service_impl) << "if (" << msgvar << ".Type_ = TMessageType.Exception) then begin" << '\n'; indent_up_impl(); - indent_impl(s_service_impl) << appexvar << " := TApplicationException.Read(iprot_);" << endl; - indent_impl(s_service_impl) << "iprot_.ReadMessageEnd();" << endl; - indent_impl(s_service_impl) << "raise " << appexvar << ";" << endl; + indent_impl(s_service_impl) << appexvar << " := TApplicationException.Read(iprot_);" << '\n'; + indent_impl(s_service_impl) << "iprot_.ReadMessageEnd();" << '\n'; + indent_impl(s_service_impl) << "raise " << appexvar << ";" << '\n'; indent_down_impl(); - indent_impl(s_service_impl) << "end;" << endl; + indent_impl(s_service_impl) << "end;" << '\n'; - indent_impl(s_service_impl) << retvar << " := " << result_clsnm << "Impl.Create();" << endl; - indent_impl(s_service_impl) << retvar << ".Read(iprot_);" << endl; - indent_impl(s_service_impl) << "iprot_.ReadMessageEnd();" << endl; + indent_impl(s_service_impl) << retvar << " := " << result_clsnm << "Impl.Create();" << '\n'; + indent_impl(s_service_impl) << retvar << ".Read(iprot_);" << '\n'; + indent_impl(s_service_impl) << "iprot_.ReadMessageEnd();" << '\n'; if (!(*f_iter)->get_returntype()->is_void()) { - indent_impl(s_service_impl) << "if (" << retvar << ".__isset_success) then begin" << endl; + indent_impl(s_service_impl) << "if (" << retvar << ".__isset_success) then begin" << '\n'; indent_up_impl(); - indent_impl(s_service_impl) << "Result := " << retvar << ".Success;" << endl; + indent_impl(s_service_impl) << "Result := " << retvar << ".Success;" << '\n'; t_type* type = (*f_iter)->get_returntype(); if (type->is_struct() || type->is_xception() || type->is_map() || type->is_list() || type->is_set()) { - indent_impl(s_service_impl) << retvar << ".Success := nil;" << endl; + indent_impl(s_service_impl) << retvar << ".Success := nil;" << '\n'; } - indent_impl(s_service_impl) << "Exit;" << endl; + indent_impl(s_service_impl) << "Exit;" << '\n'; indent_down_impl(); - indent_impl(s_service_impl) << "end;" << endl; + indent_impl(s_service_impl) << "end;" << '\n'; } vector::const_iterator x_iter; for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { indent_impl(s_service_impl) << "if (" << retvar << "." << prop_name(*x_iter, false, "__isset_") - << ") then begin" << endl; + << ") then begin" << '\n'; indent_up_impl(); - indent_impl(s_service_impl) << exceptvar << " := " << retvar << "." << prop_name(*x_iter) - << ".CreateException;" << endl; - indent_impl(s_service_impl) << "raise " << exceptvar << ";" << endl; + indent_impl(s_service_impl) << exceptvar + << " := " << type_name((*x_iter)->get_type(),true,true/*,false,true*/) + << ".Create(" << retvar << "." << prop_name(*x_iter) << ");" + << '\n'; + indent_impl(s_service_impl) << "raise " << exceptvar << ";" << '\n'; indent_down_impl(); - indent_impl(s_service_impl) << "end;" << endl; + indent_impl(s_service_impl) << "end;" << '\n'; } if (!(*f_iter)->get_returntype()->is_void()) { indent_impl(s_service_impl) << "raise TApplicationExceptionMissingResult.Create('" - << (*f_iter)->get_name() << " failed: unknown result');" << endl; + << (*f_iter)->get_name() << " failed: unknown result');" << '\n'; } indent_down_impl(); - indent_impl(s_service_impl) << "end;" << endl << endl; + indent_impl(s_service_impl) << "end;" << '\n' << '\n'; } } indent_down(); - indent(s_service) << "end;" << endl << endl; + indent(s_service) << "end;" + << render_deprecation_attribute( tservice->annotations_, " {", "}") + << '\n' << '\n'; } void t_delphi_generator::generate_service_server(t_service* tservice) { @@ -2249,164 +2249,164 @@ void t_delphi_generator::generate_service_server(t_service* tservice) { if (tservice->get_extends() != nullptr) { extends = type_name(tservice->get_extends(), true, true); extends_processor = extends + ".TProcessorImpl"; - indent(s_service) << "TProcessorImpl = class(" << extends_processor << ", IProcessor)" << endl; + indent(s_service) << "TProcessorImpl = class(" << extends_processor << ", IProcessor)" << '\n'; } else { - indent(s_service) << "TProcessorImpl = class( TInterfacedObject, IProcessor)" << endl; + indent(s_service) << "TProcessorImpl = class( TInterfacedObject, IProcessor)" << '\n'; } - indent(s_service) << "public" << endl; + indent(s_service) << "public" << '\n'; indent_up(); - indent(s_service) << "constructor Create( iface_: Iface );" << endl; - indent(s_service) << "destructor Destroy; override;" << endl; + indent(s_service) << "constructor Create( iface_: Iface );" << '\n'; + indent(s_service) << "destructor Destroy; override;" << '\n'; indent_down(); - indent_impl(s_service_impl) << "constructor " << full_cls << ".Create( iface_: Iface );" << endl; - indent_impl(s_service_impl) << "begin" << endl; + indent_impl(s_service_impl) << "constructor " << full_cls << ".Create( iface_: Iface );" << '\n'; + indent_impl(s_service_impl) << "begin" << '\n'; indent_up_impl(); if (tservice->get_extends() != nullptr) { - indent_impl(s_service_impl) << "inherited Create( iface_);" << endl; + indent_impl(s_service_impl) << "inherited Create( iface_);" << '\n'; } else { - indent_impl(s_service_impl) << "inherited Create;" << endl; + indent_impl(s_service_impl) << "inherited Create;" << '\n'; } - indent_impl(s_service_impl) << "Self.iface_ := iface_;" << endl; + indent_impl(s_service_impl) << "Self.iface_ := iface_;" << '\n'; if (tservice->get_extends() != nullptr) { - indent_impl(s_service_impl) << "ASSERT( processMap_ <> nil); // inherited" << endl; + indent_impl(s_service_impl) << "ASSERT( processMap_ <> nil); // inherited" << '\n'; } else { indent_impl(s_service_impl) - << "processMap_ := TThriftDictionaryImpl.Create;" << endl; + << "processMap_ := TThriftDictionaryImpl.Create;" << '\n'; } for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { indent_impl(s_service_impl) << "processMap_.AddOrSetValue( '" << (*f_iter)->get_name() << "', " - << (*f_iter)->get_name() << "_Process);" << endl; + << (*f_iter)->get_name() << "_Process);" << '\n'; } indent_down_impl(); - indent_impl(s_service_impl) << "end;" << endl << endl; + indent_impl(s_service_impl) << "end;" << '\n' << '\n'; - indent_impl(s_service_impl) << "destructor " << full_cls << ".Destroy;" << endl; - indent_impl(s_service_impl) << "begin" << endl; + indent_impl(s_service_impl) << "destructor " << full_cls << ".Destroy;" << '\n'; + indent_impl(s_service_impl) << "begin" << '\n'; indent_up_impl(); - indent_impl(s_service_impl) << "inherited;" << endl; + indent_impl(s_service_impl) << "inherited;" << '\n'; indent_down_impl(); - indent_impl(s_service_impl) << "end;" << endl << endl; + indent_impl(s_service_impl) << "end;" << '\n' << '\n'; - indent(s_service) << "private" << endl; + indent(s_service) << "private" << '\n'; indent_up(); - indent(s_service) << "iface_: Iface;" << endl; + indent(s_service) << "iface_: Iface;" << '\n'; indent_down(); if (tservice->get_extends() == nullptr) { - indent(s_service) << "protected" << endl; + indent(s_service) << "protected" << '\n'; indent_up(); - indent(s_service) << "type" << endl; + indent(s_service) << "type" << '\n'; indent_up(); indent(s_service) << "TProcessFunction = reference to procedure( seqid: System.Integer; const iprot: " "IProtocol; const oprot: IProtocol" - << (events_ ? "; const events : IRequestEvents" : "") << ");" << endl; + << (events_ ? "; const events : IRequestEvents" : "") << ");" << '\n'; indent_down(); indent_down(); - indent(s_service) << "protected" << endl; + indent(s_service) << "protected" << '\n'; indent_up(); - indent(s_service) << "processMap_: IThriftDictionary;" << endl; + indent(s_service) << "processMap_: IThriftDictionary;" << '\n'; indent_down(); } - indent(s_service) << "public" << endl; + indent(s_service) << "public" << '\n'; indent_up(); if (extends.empty()) { indent(s_service) << "function Process( const iprot: IProtocol; const oprot: IProtocol; const " - "events : IProcessorEvents): System.Boolean;" << endl; + "events : IProcessorEvents): System.Boolean;" << '\n'; } else { indent(s_service) << "function Process( const iprot: IProtocol; const oprot: IProtocol; const " - "events : IProcessorEvents): System.Boolean; reintroduce;" << endl; + "events : IProcessorEvents): System.Boolean; reintroduce;" << '\n'; } indent_impl(s_service_impl) << "function " << full_cls << ".Process( const iprot: IProtocol; " "const oprot: IProtocol; const events " - ": IProcessorEvents): System.Boolean;" << endl; + ": IProcessorEvents): System.Boolean;" << '\n'; ; - indent_impl(s_service_impl) << "var" << endl; + indent_impl(s_service_impl) << "var" << '\n'; indent_up_impl(); - indent_impl(s_service_impl) << "msg : Thrift.Protocol.TThriftMessage;" << endl; - indent_impl(s_service_impl) << "fn : TProcessFunction;" << endl; - indent_impl(s_service_impl) << "x : TApplicationException;" << endl; + indent_impl(s_service_impl) << "msg : Thrift.Protocol.TThriftMessage;" << '\n'; + indent_impl(s_service_impl) << "fn : TProcessFunction;" << '\n'; + indent_impl(s_service_impl) << "x : TApplicationException;" << '\n'; if (events_) { - indent_impl(s_service_impl) << "context : IRequestEvents;" << endl; + indent_impl(s_service_impl) << "context : IRequestEvents;" << '\n'; } indent_down_impl(); - indent_impl(s_service_impl) << "begin" << endl; + indent_impl(s_service_impl) << "begin" << '\n'; indent_up_impl(); - indent_impl(s_service_impl) << "try" << endl; + indent_impl(s_service_impl) << "try" << '\n'; indent_up_impl(); - indent_impl(s_service_impl) << "msg := iprot.ReadMessageBegin();" << endl; - indent_impl(s_service_impl) << "fn := nil;" << endl; - indent_impl(s_service_impl) << "if not processMap_.TryGetValue(msg.Name, fn)" << endl; - indent_impl(s_service_impl) << "or not Assigned(fn) then begin" << endl; + indent_impl(s_service_impl) << "msg := iprot.ReadMessageBegin();" << '\n'; + indent_impl(s_service_impl) << "fn := nil;" << '\n'; + indent_impl(s_service_impl) << "if not processMap_.TryGetValue(msg.Name, fn)" << '\n'; + indent_impl(s_service_impl) << "or not Assigned(fn) then begin" << '\n'; indent_up_impl(); - indent_impl(s_service_impl) << "TProtocolUtil.Skip(iprot, TType.Struct);" << endl; - indent_impl(s_service_impl) << "iprot.ReadMessageEnd();" << endl; + indent_impl(s_service_impl) << "TProtocolUtil.Skip(iprot, TType.Struct);" << '\n'; + indent_impl(s_service_impl) << "iprot.ReadMessageEnd();" << '\n'; indent_impl(s_service_impl) << "x := " "TApplicationExceptionUnknownMethod.Create(" - "'Invalid method name: ''' + msg.Name + '''');" << endl; + "'Invalid method name: ''' + msg.Name + '''');" << '\n'; indent_impl(s_service_impl) << "Thrift.Protocol.Init( msg, msg.Name, TMessageType.Exception, msg.SeqID);" - << endl; - indent_impl(s_service_impl) << "oprot.WriteMessageBegin( msg);" << endl; - indent_impl(s_service_impl) << "x.Write(oprot);" << endl; - indent_impl(s_service_impl) << "oprot.WriteMessageEnd();" << endl; - indent_impl(s_service_impl) << "oprot.Transport.Flush();" << endl; - indent_impl(s_service_impl) << "Result := True;" << endl; - indent_impl(s_service_impl) << "Exit;" << endl; + << '\n'; + indent_impl(s_service_impl) << "oprot.WriteMessageBegin( msg);" << '\n'; + indent_impl(s_service_impl) << "x.Write(oprot);" << '\n'; + indent_impl(s_service_impl) << "oprot.WriteMessageEnd();" << '\n'; + indent_impl(s_service_impl) << "oprot.Transport.Flush();" << '\n'; + indent_impl(s_service_impl) << "Result := True;" << '\n'; + indent_impl(s_service_impl) << "Exit;" << '\n'; indent_down_impl(); - indent_impl(s_service_impl) << "end;" << endl; + indent_impl(s_service_impl) << "end;" << '\n'; if (events_) { - indent_impl(s_service_impl) << "if events <> nil" << endl; - indent_impl(s_service_impl) << "then context := events.CreateRequestContext(msg.Name)" << endl; - indent_impl(s_service_impl) << "else context := nil;" << endl; - indent_impl(s_service_impl) << "try" << endl; + indent_impl(s_service_impl) << "if events <> nil" << '\n'; + indent_impl(s_service_impl) << "then context := events.CreateRequestContext(msg.Name)" << '\n'; + indent_impl(s_service_impl) << "else context := nil;" << '\n'; + indent_impl(s_service_impl) << "try" << '\n'; indent_up_impl(); - indent_impl(s_service_impl) << "fn(msg.SeqID, iprot, oprot, context);" << endl; + indent_impl(s_service_impl) << "fn(msg.SeqID, iprot, oprot, context);" << '\n'; indent_down_impl(); - indent_impl(s_service_impl) << "finally" << endl; + indent_impl(s_service_impl) << "finally" << '\n'; indent_up_impl(); - indent_impl(s_service_impl) << "if context <> nil then begin" << endl; + indent_impl(s_service_impl) << "if context <> nil then begin" << '\n'; indent_up_impl(); - indent_impl(s_service_impl) << "context.CleanupContext;" << endl; - indent_impl(s_service_impl) << "context := nil;" << endl; + indent_impl(s_service_impl) << "context.CleanupContext;" << '\n'; + indent_impl(s_service_impl) << "context := nil;" << '\n'; indent_down_impl(); - indent_impl(s_service_impl) << "end;" << endl; + indent_impl(s_service_impl) << "end;" << '\n'; indent_down_impl(); - indent_impl(s_service_impl) << "end;" << endl; + indent_impl(s_service_impl) << "end;" << '\n'; } else { - indent_impl(s_service_impl) << "fn(msg.SeqID, iprot, oprot);" << endl; + indent_impl(s_service_impl) << "fn(msg.SeqID, iprot, oprot);" << '\n'; } indent_down_impl(); - indent_impl(s_service_impl) << "except" << endl; + indent_impl(s_service_impl) << "except" << '\n'; indent_up_impl(); - indent_impl(s_service_impl) << "on TTransportExceptionTimedOut do begin" << endl; + indent_impl(s_service_impl) << "on TTransportExceptionTimedOut do begin" << '\n'; indent_up_impl(); - indent_impl(s_service_impl) << "Result := True;" << endl; - indent_impl(s_service_impl) << "Exit;" << endl; + indent_impl(s_service_impl) << "Result := True;" << '\n'; + indent_impl(s_service_impl) << "Exit;" << '\n'; indent_down_impl(); - indent_impl(s_service_impl) << "end;" << endl; - indent_impl(s_service_impl) << "else begin" << endl; + indent_impl(s_service_impl) << "end;" << '\n'; + indent_impl(s_service_impl) << "else begin" << '\n'; indent_up_impl(); - indent_impl(s_service_impl) << "Result := False;" << endl; - indent_impl(s_service_impl) << "Exit;" << endl; + indent_impl(s_service_impl) << "Result := False;" << '\n'; + indent_impl(s_service_impl) << "Exit;" << '\n'; indent_down_impl(); - indent_impl(s_service_impl) << "end;" << endl; + indent_impl(s_service_impl) << "end;" << '\n'; indent_down_impl(); - indent_impl(s_service_impl) << "end;" << endl; - indent_impl(s_service_impl) << "Result := True;" << endl; + indent_impl(s_service_impl) << "end;" << '\n'; + indent_impl(s_service_impl) << "Result := True;" << '\n'; indent_down_impl(); - indent_impl(s_service_impl) << "end;" << endl << endl; + indent_impl(s_service_impl) << "end;" << '\n' << '\n'; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { generate_process_function(tservice, *f_iter); } indent_down(); - indent(s_service) << "end;" << endl << endl; + indent(s_service) << "end;" << '\n' << '\n'; } void t_delphi_generator::generate_function_helpers(t_function* tfunction) { @@ -2420,18 +2420,21 @@ void t_delphi_generator::generate_function_helpers(t_function* tfunction) { result.append(&success); } + int num_excepts = 0; t_struct* xs = tfunction->get_xceptions(); const vector& fields = xs->get_members(); vector::const_iterator f_iter; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { result.append(*f_iter); + ++num_excepts; } + result.set_method_xcepts(num_excepts > 0); - generate_delphi_struct_definition(s_service, &result, false, true, true); + generate_delphi_struct_definition(s_service, &result); generate_delphi_struct_impl(s_service_impl, normalize_clsnm(service_name_, "T") + ".", &result, - false); + true, false); } void t_delphi_generator::generate_process_function(t_service* tservice, t_function* tfunction) { @@ -2449,46 +2452,46 @@ void t_delphi_generator::generate_process_function(t_service* tservice, t_functi indent(s_service) << "procedure " << funcname << "_Process( seqid: System.Integer; const iprot: IProtocol; const oprot: IProtocol" - << (events_ ? "; const events : IRequestEvents" : "") << ");" << endl; + << (events_ ? "; const events : IRequestEvents" : "") << ");" << '\n'; if (tfunction->is_oneway()) { - indent_impl(s_service_impl) << "// one way processor" << endl; + indent_impl(s_service_impl) << "// one way processor" << '\n'; } else { - indent_impl(s_service_impl) << "// both way processor" << endl; + indent_impl(s_service_impl) << "// both way processor" << '\n'; } indent_impl(s_service_impl) << "procedure " << full_cls << "." << funcname << "_Process( seqid: System.Integer; const iprot: IProtocol; const oprot: IProtocol" - << (events_ ? "; const events : IRequestEvents" : "") << ");" << endl; - indent_impl(s_service_impl) << "var" << endl; + << (events_ ? "; const events : IRequestEvents" : "") << ");" << '\n'; + indent_impl(s_service_impl) << "var" << '\n'; indent_up_impl(); - indent_impl(s_service_impl) << "args: " << args_intfnm << ";" << endl; + indent_impl(s_service_impl) << "args: " << args_intfnm << ";" << '\n'; if (!tfunction->is_oneway()) { - indent_impl(s_service_impl) << "msg: Thrift.Protocol.TThriftMessage;" << endl; - indent_impl(s_service_impl) << "ret: " << result_intfnm << ";" << endl; - indent_impl(s_service_impl) << "appx : TApplicationException;" << endl; + indent_impl(s_service_impl) << "msg: Thrift.Protocol.TThriftMessage;" << '\n'; + indent_impl(s_service_impl) << "ret: " << result_intfnm << ";" << '\n'; + indent_impl(s_service_impl) << "appx : TApplicationException;" << '\n'; } indent_down_impl(); - indent_impl(s_service_impl) << "begin" << endl; + indent_impl(s_service_impl) << "begin" << '\n'; indent_up_impl(); if (!tfunction->is_oneway()) { - indent_impl(s_service_impl) << "ret := " << result_clsnm << "Impl.Create;" << endl; + indent_impl(s_service_impl) << "ret := " << result_clsnm << "Impl.Create;" << '\n'; } - indent_impl(s_service_impl) << "try" << endl; + indent_impl(s_service_impl) << "try" << '\n'; indent_up_impl(); if (events_) { - indent_impl(s_service_impl) << "if events <> nil then events.PreRead;" << endl; + indent_impl(s_service_impl) << "if events <> nil then events.PreRead;" << '\n'; } - indent_impl(s_service_impl) << "args := " << args_clsnm << "Impl.Create;" << endl; - indent_impl(s_service_impl) << "args.Read(iprot);" << endl; - indent_impl(s_service_impl) << "iprot.ReadMessageEnd();" << endl; + indent_impl(s_service_impl) << "args := " << args_clsnm << "Impl.Create;" << '\n'; + indent_impl(s_service_impl) << "args.Read(iprot);" << '\n'; + indent_impl(s_service_impl) << "iprot.ReadMessageEnd();" << '\n'; if (events_) { - indent_impl(s_service_impl) << "if events <> nil then events.PostRead;" << endl; + indent_impl(s_service_impl) << "if events <> nil then events.PostRead;" << '\n'; } t_struct* xs = tfunction->get_xceptions(); @@ -2513,88 +2516,85 @@ void t_delphi_generator::generate_process_function(t_service* tservice, t_functi } s_service_impl << "args." << prop_name(*f_iter); } - s_service_impl << ");" << endl; + s_service_impl << ");" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { indent_impl(s_service_impl) << "args." << prop_name(*f_iter) - << " := " << empty_value((*f_iter)->get_type()) << ";" << endl; + << " := " << empty_value((*f_iter)->get_type()) << ";" << '\n'; } indent_down_impl(); - indent_impl(s_service_impl) << "except" << endl; + indent_impl(s_service_impl) << "except" << '\n'; indent_up_impl(); for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { indent_impl(s_service_impl) << "on E: " << type_name((*x_iter)->get_type(), true, true) - << " do begin" << endl; + << " do begin" << '\n'; indent_up_impl(); if (!tfunction->is_oneway()) { - string factory_name = normalize_clsnm((*x_iter)->get_type()->get_name(), "", true) - + "Factory"; - indent_impl(s_service_impl) << "ret." << prop_name(*x_iter) << " := E." << factory_name << ";" - << endl; + indent_impl(s_service_impl) << "ret." << prop_name(*x_iter) << " := E.ExceptionData;" << '\n'; } indent_down_impl(); - indent_impl(s_service_impl) << "end;" << endl; + indent_impl(s_service_impl) << "end;" << '\n'; } - indent_impl(s_service_impl) << "on E: Exception do begin" << endl; + indent_impl(s_service_impl) << "on E: Exception do begin" << '\n'; indent_up_impl(); if(events_) { - indent_impl(s_service_impl) << "if events <> nil then events.UnhandledError(E);" << endl; + indent_impl(s_service_impl) << "if events <> nil then events.UnhandledError(E);" << '\n'; } if (!tfunction->is_oneway()) { indent_impl(s_service_impl) << "appx := TApplicationExceptionInternalError.Create(E.Message);" - << endl; - indent_impl(s_service_impl) << "try" << endl; + << '\n'; + indent_impl(s_service_impl) << "try" << '\n'; indent_up_impl(); if(events_) { - indent_impl(s_service_impl) << "if events <> nil then events.PreWrite;" << endl; + indent_impl(s_service_impl) << "if events <> nil then events.PreWrite;" << '\n'; } indent_impl(s_service_impl) << "Thrift.Protocol.Init( msg, '" << tfunction->get_name() << "', TMessageType.Exception, seqid);" - << endl; - indent_impl(s_service_impl) << "oprot.WriteMessageBegin( msg);" << endl; - indent_impl(s_service_impl) << "appx.Write(oprot);" << endl; - indent_impl(s_service_impl) << "oprot.WriteMessageEnd();" << endl; - indent_impl(s_service_impl) << "oprot.Transport.Flush();" << endl; + << '\n'; + indent_impl(s_service_impl) << "oprot.WriteMessageBegin( msg);" << '\n'; + indent_impl(s_service_impl) << "appx.Write(oprot);" << '\n'; + indent_impl(s_service_impl) << "oprot.WriteMessageEnd();" << '\n'; + indent_impl(s_service_impl) << "oprot.Transport.Flush();" << '\n'; if(events_) { - indent_impl(s_service_impl) << "if events <> nil then events.PostWrite;" << endl; + indent_impl(s_service_impl) << "if events <> nil then events.PostWrite;" << '\n'; } - indent_impl(s_service_impl) << "Exit;" << endl; + indent_impl(s_service_impl) << "Exit;" << '\n'; indent_down_impl(); - indent_impl(s_service_impl) << "finally" << endl; + indent_impl(s_service_impl) << "finally" << '\n'; indent_up_impl(); - indent_impl(s_service_impl) << "appx.Free;" << endl; + indent_impl(s_service_impl) << "appx.Free;" << '\n'; indent_down_impl(); - indent_impl(s_service_impl) << "end;" << endl; + indent_impl(s_service_impl) << "end;" << '\n'; } indent_down_impl(); - indent_impl(s_service_impl) << "end;" << endl; + indent_impl(s_service_impl) << "end;" << '\n'; indent_down_impl(); - indent_impl(s_service_impl) << "end;" << endl; + indent_impl(s_service_impl) << "end;" << '\n'; if (!tfunction->is_oneway()) { if (events_) { - indent_impl(s_service_impl) << "if events <> nil then events.PreWrite;" << endl; + indent_impl(s_service_impl) << "if events <> nil then events.PreWrite;" << '\n'; } indent_impl(s_service_impl) << "Thrift.Protocol.Init( msg, '" << tfunction->get_name() << "', TMessageType.Reply, seqid); " - << endl; - indent_impl(s_service_impl) << "oprot.WriteMessageBegin( msg); " << endl; - indent_impl(s_service_impl) << "ret.Write(oprot);" << endl; - indent_impl(s_service_impl) << "oprot.WriteMessageEnd();" << endl; - indent_impl(s_service_impl) << "oprot.Transport.Flush();" << endl; + << '\n'; + indent_impl(s_service_impl) << "oprot.WriteMessageBegin( msg); " << '\n'; + indent_impl(s_service_impl) << "ret.Write(oprot);" << '\n'; + indent_impl(s_service_impl) << "oprot.WriteMessageEnd();" << '\n'; + indent_impl(s_service_impl) << "oprot.Transport.Flush();" << '\n'; if (events_) { - indent_impl(s_service_impl) << "if events <> nil then events.PostWrite;" << endl; + indent_impl(s_service_impl) << "if events <> nil then events.PostWrite;" << '\n'; } } else if (events_) { - indent_impl(s_service_impl) << "if events <> nil then events.OnewayComplete;" << endl; + indent_impl(s_service_impl) << "if events <> nil then events.OnewayComplete;" << '\n'; } indent_down_impl(); - indent_impl(s_service_impl) << "end;" << endl << endl; + indent_impl(s_service_impl) << "end;" << '\n' << '\n'; } void t_delphi_generator::generate_deserialize_field(ostream& out, @@ -2602,10 +2602,7 @@ void t_delphi_generator::generate_deserialize_field(ostream& out, t_field* tfield, string prefix, ostream& local_vars) { - t_type* type = tfield->get_type(); - while (type->is_typedef()) { - type = ((t_typedef*)type)->get_type(); - } + t_type* type = tfield->get_type()->get_true_type(); if (type->is_void()) { throw "CANNOT GENERATE DESERIALIZE CODE FOR void TYPE: " + prefix + tfield->get_name(); @@ -2634,11 +2631,7 @@ void t_delphi_generator::generate_deserialize_field(ostream& out, break; case t_base_type::TYPE_STRING: if (type->is_binary()) { - if (ansistr_binary_) { - out << "ReadAnsiString();"; - } else { - out << (com_types_ ? "ReadBinaryCOM();" : "ReadBinary();"); - } + out << (com_types_ ? "ReadBinaryCOM();" : "ReadBinary();"); } else { out << "ReadString();"; } @@ -2671,7 +2664,7 @@ void t_delphi_generator::generate_deserialize_field(ostream& out, out << "ReadI32()"; out << ");"; } - out << endl; + out << '\n'; } else { printf("DO NOT KNOW HOW TO DESERIALIZE FIELD '%s' TYPE '%s'\n", tfield->get_name().c_str(), @@ -2685,14 +2678,10 @@ void t_delphi_generator::generate_deserialize_struct(ostream& out, string prefix) { string typ_name; - if (tstruct->is_xception()) { - typ_name = type_name(tstruct, true, false, true, true); - } else { - typ_name = type_name(tstruct, true, false); - } + typ_name = type_name(tstruct, true, false); - indent_impl(out) << prefix << name << " := " << typ_name << ".Create;" << endl; - indent_impl(out) << prefix << name << ".Read(iprot);" << endl; + indent_impl(out) << prefix << name << " := " << typ_name << ".Create;" << '\n'; + indent_impl(out) << prefix << name << ".Read(iprot);" << '\n'; } void t_delphi_generator::generate_deserialize_container(ostream& out, @@ -2720,22 +2709,22 @@ void t_delphi_generator::generate_deserialize_container(ostream& out, } else if (ttype->is_list()) { local_var = obj + ": TThriftList;"; } - local_vars << " " << local_var << endl; + local_vars << " " << local_var << '\n'; counter = tmp("_i"); local_var = counter + ": System.Integer;"; - local_vars << " " << local_var << endl; + local_vars << " " << local_var << '\n'; - indent_impl(out) << name << " := " << type_name(ttype, true) << ".Create;" << endl; + indent_impl(out) << name << " := " << type_name(ttype, true) << ".Create;" << '\n'; if (ttype->is_map()) { - indent_impl(out) << obj << " := iprot.ReadMapBegin();" << endl; + indent_impl(out) << obj << " := iprot.ReadMapBegin();" << '\n'; } else if (ttype->is_set()) { - indent_impl(out) << obj << " := iprot.ReadSetBegin();" << endl; + indent_impl(out) << obj << " := iprot.ReadSetBegin();" << '\n'; } else if (ttype->is_list()) { - indent_impl(out) << obj << " := iprot.ReadListBegin();" << endl; + indent_impl(out) << obj << " := iprot.ReadListBegin();" << '\n'; } - indent_impl(out) << "for " << counter << " := 0 to " << obj << ".Count - 1 do begin" << endl; + indent_impl(out) << "for " << counter << " := 0 to " << obj << ".Count - 1 do begin" << '\n'; indent_up_impl(); if (ttype->is_map()) { generate_deserialize_map_element(out, is_xception, (t_map*)ttype, name, local_vars); @@ -2745,14 +2734,14 @@ void t_delphi_generator::generate_deserialize_container(ostream& out, generate_deserialize_list_element(out, is_xception, (t_list*)ttype, name, local_vars); } indent_down_impl(); - indent_impl(out) << "end;" << endl; + indent_impl(out) << "end;" << '\n'; if (ttype->is_map()) { - indent_impl(out) << "iprot.ReadMapEnd();" << endl; + indent_impl(out) << "iprot.ReadMapEnd();" << '\n'; } else if (ttype->is_set()) { - indent_impl(out) << "iprot.ReadSetEnd();" << endl; + indent_impl(out) << "iprot.ReadSetEnd();" << '\n'; } else if (ttype->is_list()) { - indent_impl(out) << "iprot.ReadListEnd();" << endl; + indent_impl(out) << "iprot.ReadListEnd();" << '\n'; } } @@ -2769,13 +2758,13 @@ void t_delphi_generator::generate_deserialize_map_element(ostream& out, t_field fkey(tmap->get_key_type(), key); t_field fval(tmap->get_val_type(), val); - local_vars << " " << declare_field(&fkey) << endl; - local_vars << " " << declare_field(&fval) << endl; + local_vars << " " << declare_field(&fkey) << '\n'; + local_vars << " " << declare_field(&fval) << '\n'; generate_deserialize_field(out, is_xception, &fkey, "", local_vars); generate_deserialize_field(out, is_xception, &fval, "", local_vars); - indent_impl(out) << prefix << ".AddOrSetValue( " << key << ", " << val << ");" << endl; + indent_impl(out) << prefix << ".AddOrSetValue( " << key << ", " << val << ");" << '\n'; } void t_delphi_generator::generate_deserialize_set_element(ostream& out, @@ -2785,9 +2774,9 @@ void t_delphi_generator::generate_deserialize_set_element(ostream& out, ostream& local_vars) { string elem = tmp("_elem"); t_field felem(tset->get_elem_type(), elem); - local_vars << " " << declare_field(&felem) << endl; + local_vars << " " << declare_field(&felem) << '\n'; generate_deserialize_field(out, is_xception, &felem, "", local_vars); - indent_impl(out) << prefix << ".Add(" << elem << ");" << endl; + indent_impl(out) << prefix << ".Add(" << elem << ");" << '\n'; } void t_delphi_generator::generate_deserialize_list_element(ostream& out, @@ -2797,9 +2786,9 @@ void t_delphi_generator::generate_deserialize_list_element(ostream& out, ostream& local_vars) { string elem = tmp("_elem"); t_field felem(tlist->get_elem_type(), elem); - local_vars << " " << declare_field(&felem) << endl; + local_vars << " " << declare_field(&felem) << '\n'; generate_deserialize_field(out, is_xception, &felem, "", local_vars); - indent_impl(out) << prefix << ".Add(" << elem << ");" << endl; + indent_impl(out) << prefix << ".Add(" << elem << ");" << '\n'; } void t_delphi_generator::generate_serialize_field(ostream& out, @@ -2809,10 +2798,7 @@ void t_delphi_generator::generate_serialize_field(ostream& out, ostream& local_vars) { (void)local_vars; - t_type* type = tfield->get_type(); - while (type->is_typedef()) { - type = ((t_typedef*)type)->get_type(); - } + t_type* type = tfield->get_type()->get_true_type(); string name = prefix + prop_name(tfield, is_xception); @@ -2837,11 +2823,7 @@ void t_delphi_generator::generate_serialize_field(ostream& out, break; case t_base_type::TYPE_STRING: if (type->is_binary()) { - if (ansistr_binary_) { - out << "WriteAnsiString("; - } else { - out << "WriteBinary("; - } + out << "WriteBinary("; } else { out << "WriteString("; } @@ -2874,7 +2856,7 @@ void t_delphi_generator::generate_serialize_field(ostream& out, } else if (type->is_enum()) { out << "WriteI32(System.Integer(" << name << "));"; } - out << endl; + out << '\n'; } else { printf("DO NOT KNOW HOW TO SERIALIZE '%s%s' TYPE '%s'\n", prefix.c_str(), @@ -2889,7 +2871,7 @@ void t_delphi_generator::generate_serialize_struct(ostream& out, ostream& local_vars) { (void)local_vars; (void)tstruct; - out << indent_impl() << prefix << ".Write(oprot);" << endl; + out << indent_impl() << prefix << ".Write(oprot);" << '\n'; } void t_delphi_generator::generate_serialize_container(ostream& out, @@ -2900,42 +2882,42 @@ void t_delphi_generator::generate_serialize_container(ostream& out, string obj; if (ttype->is_map()) { obj = tmp("map"); - local_vars << " " << obj << " : TThriftMap;" << endl; + local_vars << " " << obj << " : TThriftMap;" << '\n'; indent_impl(out) << "Thrift.Protocol.Init( " << obj << ", " << type_to_enum(((t_map*)ttype)->get_key_type()) << ", " << type_to_enum(((t_map*)ttype)->get_val_type()) << ", " << prefix - << ".Count);" << endl; - indent_impl(out) << "oprot.WriteMapBegin( " << obj << ");" << endl; + << ".Count);" << '\n'; + indent_impl(out) << "oprot.WriteMapBegin( " << obj << ");" << '\n'; } else if (ttype->is_set()) { obj = tmp("set_"); - local_vars << " " << obj << " : TThriftSet;" << endl; + local_vars << " " << obj << " : TThriftSet;" << '\n'; indent_impl(out) << "Thrift.Protocol.Init( " << obj << ", " << type_to_enum(((t_set*)ttype)->get_elem_type()) << ", " << prefix - << ".Count);" << endl; - indent_impl(out) << "oprot.WriteSetBegin( " << obj << ");" << endl; + << ".Count);" << '\n'; + indent_impl(out) << "oprot.WriteSetBegin( " << obj << ");" << '\n'; } else if (ttype->is_list()) { obj = tmp("list_"); - local_vars << " " << obj << " : TThriftList;" << endl; + local_vars << " " << obj << " : TThriftList;" << '\n'; indent_impl(out) << "Thrift.Protocol.Init( " << obj << ", " << type_to_enum(((t_list*)ttype)->get_elem_type()) << ", " << prefix - << ".Count);" << endl; - indent_impl(out) << "oprot.WriteListBegin( " << obj << ");" << endl; + << ".Count);" << '\n'; + indent_impl(out) << "oprot.WriteListBegin( " << obj << ");" << '\n'; } string iter = tmp("_iter"); if (ttype->is_map()) { - local_vars << " " << iter << ": " << type_name(((t_map*)ttype)->get_key_type()) << ";" << endl; - indent_impl(out) << "for " << iter << " in " << prefix << ".Keys do begin" << endl; + local_vars << " " << iter << ": " << type_name(((t_map*)ttype)->get_key_type()) << ";" << '\n'; + indent_impl(out) << "for " << iter << " in " << prefix << ".Keys do begin" << '\n'; indent_up_impl(); } else if (ttype->is_set()) { local_vars << " " << iter << ": " << type_name(((t_set*)ttype)->get_elem_type()) << ";" - << endl; - indent_impl(out) << "for " << iter << " in " << prefix << " do begin" << endl; + << '\n'; + indent_impl(out) << "for " << iter << " in " << prefix << " do begin" << '\n'; indent_up_impl(); } else if (ttype->is_list()) { local_vars << " " << iter << ": " << type_name(((t_list*)ttype)->get_elem_type()) << ";" - << endl; - indent_impl(out) << "for " << iter << " in " << prefix << " do begin" << endl; + << '\n'; + indent_impl(out) << "for " << iter << " in " << prefix << " do begin" << '\n'; indent_up_impl(); } @@ -2948,14 +2930,14 @@ void t_delphi_generator::generate_serialize_container(ostream& out, } indent_down_impl(); - indent_impl(out) << "end;" << endl; + indent_impl(out) << "end;" << '\n'; if (ttype->is_map()) { - indent_impl(out) << "oprot.WriteMapEnd();" << endl; + indent_impl(out) << "oprot.WriteMapEnd();" << '\n'; } else if (ttype->is_set()) { - indent_impl(out) << "oprot.WriteSetEnd();" << endl; + indent_impl(out) << "oprot.WriteSetEnd();" << '\n'; } else if (ttype->is_list()) { - indent_impl(out) << "oprot.WriteListEnd();" << endl; + indent_impl(out) << "oprot.WriteListEnd();" << '\n'; } } @@ -2993,24 +2975,24 @@ void t_delphi_generator::generate_property(ostream& out, t_field* tfield, bool isPublic, bool is_xception) { - generate_delphi_property(out, is_xception, tfield, isPublic, "Get"); + generate_delphi_property(out, is_xception, tfield, isPublic); } void t_delphi_generator::generate_delphi_property(ostream& out, bool struct_is_xception, t_field* tfield, - bool isPublic, - std::string fieldPrefix) { + bool isPublic) { (void)isPublic; t_type* ftype = tfield->get_type(); - bool is_xception = ftype->is_xception(); generate_delphi_doc(out, tfield); indent(out) << "property " << prop_name(tfield, struct_is_xception) << ": " - << type_name(ftype, false, true, is_xception, true) - << " read " << prop_name(tfield, struct_is_xception, fieldPrefix) - << " write " << prop_name(tfield, struct_is_xception, "Set") - << ";" << endl; + << type_name(ftype, false, true/*, false, true*/) + << " read " << prop_name(tfield, struct_is_xception, "Get") + << " write " << prop_name(tfield, struct_is_xception, "Set") + << ";" + << render_deprecation_attribute(tfield->annotations_, " {", "}") + << '\n'; } std::string t_delphi_generator::prop_name(t_field* tfield, bool is_xception, std::string prefix) { @@ -3042,9 +3024,7 @@ string t_delphi_generator::normalize_clsnm(string clsnm, string prefix, bool b_n string t_delphi_generator::type_name(t_type* ttype, bool b_cls, - bool b_no_postfix, - bool b_exception_factory, - bool b_full_exception_factory) { + bool b_no_postfix) { if (ttype->is_typedef()) { t_typedef* tdef = (t_typedef*)ttype; @@ -3052,9 +3032,7 @@ string t_delphi_generator::type_name(t_type* ttype, if (tdef->get_type() != nullptr) { return type_name(tdef->get_type(), b_cls, - b_no_postfix, - b_exception_factory, - b_full_exception_factory); + b_no_postfix); } else { throw "unresolved forward declaration: " + tdef->get_symbolic(); } @@ -3109,20 +3087,12 @@ string t_delphi_generator::type_name(t_type* ttype, string nm = normalize_clsnm(ttype->get_name(), type_prefix); - if (b_exception_factory) { - nm = nm + "Factory"; - } - if (b_cls) { if (!b_no_postfix) { nm = nm + "Impl"; } } - if (b_exception_factory && b_full_exception_factory) { - return type_name(ttype, true, true, false, false) + "." + nm; - } - return nm; } @@ -3180,8 +3150,6 @@ string t_delphi_generator::base_type_name(t_base_type* tbase) { return ""; case t_base_type::TYPE_STRING: if (tbase->is_binary()) { - if (ansistr_binary_) - return "System.AnsiString"; if( com_types_) return "IThriftBytes"; if( rtti_) @@ -3211,16 +3179,13 @@ string t_delphi_generator::base_type_name(t_base_type* tbase) { } string t_delphi_generator::declare_field(t_field* tfield, - bool init, std::string prefix, bool is_xception_class) { - (void)init; - t_type* ftype = tfield->get_type(); - bool is_xception = ftype->is_xception(); string result = prop_name(tfield, is_xception_class, prefix) + ": " - + type_name(ftype, false, true, is_xception, true) + ";"; + + type_name(ftype, false, true) + ";"; + return result; } @@ -3237,7 +3202,7 @@ string t_delphi_generator::function_signature(t_function* tfunction, } string signature = ""; - + if( for_async) { if (is_void(ttype)) { signature = "function " + prefix + normalize_name(tfunction->get_name(), true, is_xception) + "Async(" @@ -3245,7 +3210,7 @@ string t_delphi_generator::function_signature(t_function* tfunction, } else { signature = "function " + prefix + normalize_name(tfunction->get_name(), true, is_xception) + "Async(" + argument_list(tfunction->get_arglist()) + "): IFuture<" - + type_name(ttype, false, true, is_xception, true) + ">;"; + + type_name(ttype, false, true/*, is_xception, true*/) + ">;"; } } else { if (is_void(ttype)) { @@ -3254,21 +3219,13 @@ string t_delphi_generator::function_signature(t_function* tfunction, } else { signature = "function " + prefix + normalize_name(tfunction->get_name(), true, is_xception) + "(" + argument_list(tfunction->get_arglist()) + "): " - + type_name(ttype, false, true, is_xception, true) + ";"; + + type_name(ttype, false, true/*, is_xception, true*/) + ";"; } } // deprecated method? only at intf decl! if( full_cls == "") { - auto iter = tfunction->annotations_.find("deprecated"); - if( tfunction->annotations_.end() != iter && !iter->second.empty()) { - signature += " deprecated"; - // empty annotation values end up with "1" somewhere, ignore these as well - if ((iter->second.back().length() > 0) && (iter->second.back() != "1")) { - signature += " " + make_pascal_string_literal(iter->second.back()); - } - signature += ";"; - } + signature += render_deprecation_attribute(tfunction->annotations_, " ", ";"); } return signature; @@ -3291,7 +3248,7 @@ string t_delphi_generator::argument_list(t_struct* tstruct) { tt = (*f_iter)->get_type(); result += input_arg_prefix(tt); // const? result += normalize_name((*f_iter)->get_name()) + ": " - + type_name(tt, false, true, tt->is_xception(), true); + + type_name(tt, false, true/*, tt->is_xception(), true*/); } return result; } @@ -3316,10 +3273,10 @@ string t_delphi_generator::constructor_argument_list(t_struct* tstruct, string c if (line.size() > 80) { if (firstline) { - result << endl << newline_indent; + result << '\n' << newline_indent; firstline = false; } - result << line << endl; + result << line << '\n'; line = newline_indent; } else if (line.size() > 0) { line += " "; @@ -3328,7 +3285,7 @@ string t_delphi_generator::constructor_argument_list(t_struct* tstruct, string c tt = (*f_iter)->get_type(); line += input_arg_prefix(tt); // const? line += constructor_param_name((*f_iter)->get_name()) + ": " - + type_name(tt, false, true, tt->is_xception(), true); + + type_name(tt, false, true/*, tt->is_xception(), true*/); } if (line.size() > 0) { @@ -3347,9 +3304,7 @@ string t_delphi_generator::constructor_argument_list(t_struct* tstruct, string c } string t_delphi_generator::type_to_enum(t_type* type) { - while (type->is_typedef()) { - type = ((t_typedef*)type)->get_type(); - } + type = type->get_true_type(); if (type->is_base_type()) { t_base_type::t_base tbase = ((t_base_type*)type)->get_base(); @@ -3389,9 +3344,7 @@ string t_delphi_generator::type_to_enum(t_type* type) { } string t_delphi_generator::empty_value(t_type* type) { - while (type->is_typedef()) { - type = ((t_typedef*)type)->get_type(); - } + type = type->get_true_type(); if (type->is_base_type()) { t_base_type::t_base tbase = ((t_base_type*)type)->get_base(); @@ -3400,11 +3353,7 @@ string t_delphi_generator::empty_value(t_type* type) { return "0"; case t_base_type::TYPE_STRING: if (type->is_binary()) { - if (ansistr_binary_) { - return "''"; - } else { - return "nil"; - } + return "nil"; } else { return "''"; } @@ -3439,28 +3388,30 @@ void t_delphi_generator::generate_delphi_property_writer_definition(ostream& out t_field* tfield, bool is_xception_class) { t_type* ftype = tfield->get_type(); - bool is_xception = ftype->is_xception(); indent(out) << "procedure " << prop_name(tfield, is_xception_class, "Set") - << "( const Value: " << type_name(ftype, false, true, is_xception, true) << ");" - << endl; + << "( const Value: " << type_name(ftype, false, true/*, false, true*/) << ");" + << render_deprecation_attribute(tfield->annotations_, " ", ";") + << '\n'; } void t_delphi_generator::generate_delphi_property_reader_definition(ostream& out, t_field* tfield, bool is_xception_class) { t_type* ftype = tfield->get_type(); - bool is_xception = ftype->is_xception(); indent(out) << "function " << prop_name(tfield, is_xception_class, "Get") << ": " - << type_name(ftype, false, true, is_xception, true) << ";" << endl; + << type_name(ftype, false, true/*, false*/) << ";" + << render_deprecation_attribute(tfield->annotations_, " ", ";") + << '\n'; } void t_delphi_generator::generate_delphi_isset_reader_writer_definition(ostream& out, t_field* tfield, bool is_xception) { - indent(out) << "function " << prop_name(tfield, is_xception,"Get__isset_") << ": System.Boolean;" << endl; - indent(out) << "procedure " << prop_name(tfield, is_xception, "Set__isset_") << "( const value : System.Boolean);" << endl; + (void)is_xception; + indent(out) << "function " << prop_name(tfield, false,"Get__isset_") << ": System.Boolean;" << '\n'; + indent(out) << "procedure " << prop_name(tfield, false, "Set__isset_") << "( const value : System.Boolean);" << '\n'; } void t_delphi_generator::generate_delphi_clear_union_value(ostream& out, @@ -3470,28 +3421,22 @@ void t_delphi_generator::generate_delphi_clear_union_value(ostream& out, t_field* tfield, std::string fieldPrefix, bool is_xception_class, - bool is_union, - bool is_xception_factory, - std::string xception_factory_name) { + bool is_union) { (void)cls_prefix; (void)name; (void)type; (void)is_union; - (void)is_xception_factory; - (void)xception_factory_name; t_type* ftype = tfield->get_type(); - bool is_xception = ftype->is_xception(); - indent_impl(out) << "if " << prop_name(tfield, is_xception_class,"F__isset_") << " then begin" - << endl; + indent_impl(out) << "if " << prop_name(tfield, is_xception_class,"F__isset_") << " then begin" << '\n'; indent_up_impl(); - indent_impl(out) << prop_name(tfield, is_xception_class,"F__isset_") << " := False;" << endl; + indent_impl(out) << prop_name(tfield, is_xception_class,"F__isset_") << " := False;" << '\n'; indent_impl(out) << prop_name(tfield, is_xception_class,fieldPrefix) << " := " - << "Default( " << type_name(ftype, false, true, is_xception, true) << ");" - << endl; + << "Default( " << type_name(ftype, false, true/*, is_xception, true*/) << ");" + << '\n'; indent_down_impl(); - indent_impl(out) << "end;" << endl; + indent_impl(out) << "end;" << '\n'; } void t_delphi_generator::generate_delphi_property_writer_impl(ostream& out, @@ -3501,35 +3446,31 @@ void t_delphi_generator::generate_delphi_property_writer_impl(ostream& out, t_field* tfield, std::string fieldPrefix, bool is_xception_class, - bool is_union, - bool is_xception_factory, - std::string xception_factory_name) { + bool is_union) { (void)type; t_type* ftype = tfield->get_type(); - bool is_xception = ftype->is_xception(); indent_impl(out) << "procedure " << cls_prefix << name << "." << prop_name(tfield, is_xception_class,"Set") - << "( const Value: " << type_name(ftype, false, true, is_xception, true) << ");" - << endl; - indent_impl(out) << "begin" << endl; + << "( const Value: " << type_name(ftype, false, true) << ");" + << '\n'; + indent_impl(out) << "begin" << '\n'; indent_up_impl(); if (is_union) { - indent_impl(out) << "ClearUnionValues;" << endl; + indent_impl(out) << "ClearUnionValues;" << '\n'; } - if (tfield->get_req() != t_field::T_REQUIRED) { - indent_impl(out) << prop_name(tfield, is_xception_class,"F__isset_") << " := True;" << endl; - } - indent_impl(out) << prop_name(tfield, is_xception_class,fieldPrefix) << " := Value;" << endl; - - if (is_xception_class && (!is_xception_factory)) { - indent_impl(out) << xception_factory_name << "." << prop_name(tfield, is_xception_class) - << " := Value;" << endl; + if(is_xception_class) { + indent_impl(out) << "FData." << prop_name(tfield, false, fieldPrefix) << " := Value;" << '\n'; + } else { + if (tfield->get_req() != t_field::T_REQUIRED) { + indent_impl(out) << prop_name(tfield, is_xception_class, "F__isset_") << " := True;" << '\n'; + } + indent_impl(out) << prop_name(tfield, is_xception_class, fieldPrefix) << " := Value;" << '\n'; } indent_down_impl(); - indent_impl(out) << "end;" << endl << endl; + indent_impl(out) << "end;" << '\n' << '\n'; } void t_delphi_generator::generate_delphi_property_reader_impl(ostream& out, @@ -3542,17 +3483,19 @@ void t_delphi_generator::generate_delphi_property_reader_impl(ostream& out, (void)type; t_type* ftype = tfield->get_type(); - bool is_xception = ftype->is_xception(); indent_impl(out) << "function " << cls_prefix << name << "." << prop_name(tfield, is_xception_class,"Get") << ": " - << type_name(ftype, false, true, is_xception, true) << ";" << endl; - indent_impl(out) << "begin" << endl; + << type_name(ftype, false, true) << ";" << '\n'; + indent_impl(out) << "begin" << '\n'; indent_up_impl(); - indent_impl(out) << "Result := " << prop_name(tfield, is_xception_class,fieldPrefix) << ";" - << endl; + if(is_xception_class) { + indent_impl(out) << "Result := FData." << prop_name(tfield, false, fieldPrefix) << ";" << '\n'; + } else { + indent_impl(out) << "Result := " << prop_name(tfield, is_xception_class, fieldPrefix) << ";" << '\n'; + } indent_down_impl(); - indent_impl(out) << "end;" << endl << endl; + indent_impl(out) << "end;" << '\n' << '\n'; } void t_delphi_generator::generate_delphi_isset_reader_writer_impl(ostream& out, @@ -3561,76 +3504,41 @@ void t_delphi_generator::generate_delphi_isset_reader_writer_impl(ostream& out, t_type* type, t_field* tfield, std::string fieldPrefix, - bool is_xception) { + bool is_xception_class) { (void)type; - string isset_name = prop_name(tfield, is_xception, "__isset_"); - + string isset_name = prop_name(tfield, false, "__isset_"); + indent_impl(out) << "function " << cls_prefix << name << "." - << "Get" << isset_name << ": System.Boolean;" << endl; - indent_impl(out) << "begin" << endl; + << "Get" << isset_name << ": System.Boolean;" << '\n'; + indent_impl(out) << "begin" << '\n'; indent_up_impl(); - indent_impl(out) << "Result := " << fieldPrefix << isset_name << ";" << endl; - indent_down_impl(); - indent_impl(out) << "end;" << endl << endl; - - indent_impl(out) << "procedure " << cls_prefix << name << "." - << "Set" << isset_name << "( const value: System.Boolean);" << endl; - indent_impl(out) << "begin" << endl; - indent_up_impl(); - indent_impl(out) << fieldPrefix << isset_name << " := value;" << endl; + if(is_xception_class) { + indent_impl(out) << "Result := FData." << fieldPrefix << isset_name << ";" << '\n'; + } else { + indent_impl(out) << "Result := " << fieldPrefix << isset_name << ";" << '\n'; + } indent_down_impl(); - indent_impl(out) << "end;" << endl << endl; -} - -void t_delphi_generator::generate_delphi_create_exception_impl(ostream& out, - string cls_prefix, - t_struct* tstruct, - bool is_exception) { - (void)cls_prefix; - - string exception_cls_nm = type_name(tstruct, true, true); - string cls_nm = type_name(tstruct, true, false, is_exception, is_exception); + indent_impl(out) << "end;" << '\n' << '\n'; - indent_impl(out) << "function " << cls_nm << ".CreateException: " << exception_cls_nm << ";" - << endl; - - indent_impl(out) << "begin" << endl; + indent_impl(out) << "procedure " << cls_prefix << name << "." + << "Set" << isset_name << "( const value: System.Boolean);" << '\n'; + indent_impl(out) << "begin" << '\n'; indent_up_impl(); - - indent_impl(out) << "Result := " << exception_cls_nm << ".Create;" << endl; - string factory_name = normalize_clsnm(tstruct->get_name(), "", true) + "Factory"; - indent_impl(out) << "Result.F" << factory_name << " := Self;" << endl; - - const vector& fields = tstruct->get_members(); - vector::const_iterator f_iter; - - string propname; - - for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { - propname = prop_name(*f_iter, is_exception); - if ((*f_iter)->get_req() != t_field::T_REQUIRED) { - indent_impl(out) << "if " << prop_name(*f_iter, is_exception,"__isset_") << " then begin" << endl; - indent_up_impl(); - } - indent_impl(out) << "Result." << propname << " := " << propname << ";" << endl; - if ((*f_iter)->get_req() != t_field::T_REQUIRED) { - indent_down_impl(); - indent_impl(out) << "end;" << endl; - } + if(is_xception_class) { + indent_impl(out) << "FData." << fieldPrefix << isset_name << " := value;" << '\n'; + } else { + indent_impl(out) << fieldPrefix << isset_name << " := value;" << '\n'; } - - indent_impl(out) << "Result.UpdateMessageProperty;" << endl; - indent_down_impl(); - indent_impl(out) << "end;" << endl << endl; + indent_impl(out) << "end;" << '\n' << '\n'; } + void t_delphi_generator::generate_delphi_struct_reader_impl(ostream& out, string cls_prefix, t_struct* tstruct, - bool is_exception, - bool is_x_factory) { + bool is_exception) { ostringstream local_vars; ostringstream code_block; @@ -3638,53 +3546,53 @@ void t_delphi_generator::generate_delphi_struct_reader_impl(ostream& out, const vector& fields = tstruct->get_members(); vector::const_iterator f_iter; - indent_impl(code_block) << "begin" << endl; + indent_impl(code_block) << "begin" << '\n'; indent_up_impl(); - indent_impl(local_vars) << "tracker : IProtocolRecursionTracker;" << endl; - indent_impl(code_block) << "tracker := iprot.NextRecursionLevel;" << endl; + indent_impl(local_vars) << "tracker : IProtocolRecursionTracker;" << '\n'; + indent_impl(code_block) << "tracker := iprot.NextRecursionLevel;" << '\n'; // local bools for required fields for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if ((*f_iter)->get_req() == t_field::T_REQUIRED) { indent_impl(local_vars) << prop_name(*f_iter, is_exception,"_req_isset_") << " : System.Boolean;" - << endl; + << '\n'; indent_impl(code_block) << prop_name(*f_iter, is_exception,"_req_isset_") << " := FALSE;" - << endl; + << '\n'; } } - indent_impl(code_block) << "struc := iprot.ReadStructBegin;" << endl; + indent_impl(code_block) << "struc := iprot.ReadStructBegin;" << '\n'; - indent_impl(code_block) << "try" << endl; + indent_impl(code_block) << "try" << '\n'; indent_up_impl(); - indent_impl(code_block) << "while (true) do begin" << endl; + indent_impl(code_block) << "while (true) do begin" << '\n'; indent_up_impl(); - indent_impl(code_block) << "field_ := iprot.ReadFieldBegin();" << endl; + indent_impl(code_block) << "field_ := iprot.ReadFieldBegin();" << '\n'; - indent_impl(code_block) << "if (field_.Type_ = TType.Stop) then Break;" << endl; + indent_impl(code_block) << "if (field_.Type_ = TType.Stop) then Break;" << '\n'; bool first = true; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if (first) { - code_block << endl; - indent_impl(code_block) << "case field_.ID of" << endl; + code_block << '\n'; + indent_impl(code_block) << "case field_.ID of" << '\n'; indent_up_impl(); } first = false; if (f_iter != fields.begin()) { - code_block << endl; + code_block << '\n'; } - indent_impl(code_block) << (*f_iter)->get_key() << ": begin" << endl; + indent_impl(code_block) << (*f_iter)->get_key() << ": begin" << '\n'; indent_up_impl(); indent_impl(code_block) << "if (field_.Type_ = " << type_to_enum((*f_iter)->get_type()) - << ") then begin" << endl; + << ") then begin" << '\n'; indent_up_impl(); generate_deserialize_field(code_block, is_exception, *f_iter, "Self.", local_vars); @@ -3692,155 +3600,88 @@ void t_delphi_generator::generate_delphi_struct_reader_impl(ostream& out, // required field? if ((*f_iter)->get_req() == t_field::T_REQUIRED) { indent_impl(code_block) << prop_name(*f_iter, is_exception,"_req_isset_") << " := TRUE;" - << endl; + << '\n'; } indent_down_impl(); - indent_impl(code_block) << "end else begin" << endl; + indent_impl(code_block) << "end else begin" << '\n'; indent_up_impl(); - indent_impl(code_block) << "TProtocolUtil.Skip(iprot, field_.Type_);" << endl; + indent_impl(code_block) << "TProtocolUtil.Skip(iprot, field_.Type_);" << '\n'; indent_down_impl(); - indent_impl(code_block) << "end;" << endl; + indent_impl(code_block) << "end;" << '\n'; indent_down_impl(); indent_impl(code_block) << "end;"; } if (!first) { - code_block << endl; + code_block << '\n'; indent_down_impl(); - indent_impl(code_block) << "else" << endl; + indent_impl(code_block) << "else" << '\n'; indent_up_impl(); } - indent_impl(code_block) << "TProtocolUtil.Skip(iprot, field_.Type_);" << endl; + indent_impl(code_block) << "TProtocolUtil.Skip(iprot, field_.Type_);" << '\n'; if (!first) { indent_down_impl(); - indent_impl(code_block) << "end;" << endl; + indent_impl(code_block) << "end;" << '\n'; } - indent_impl(code_block) << "iprot.ReadFieldEnd;" << endl; + indent_impl(code_block) << "iprot.ReadFieldEnd;" << '\n'; indent_down_impl(); - indent_impl(code_block) << "end;" << endl; + indent_impl(code_block) << "end;" << '\n'; indent_down_impl(); - indent_impl(code_block) << "finally" << endl; + indent_impl(code_block) << "finally" << '\n'; indent_up_impl(); - indent_impl(code_block) << "iprot.ReadStructEnd;" << endl; + indent_impl(code_block) << "iprot.ReadStructEnd;" << '\n'; indent_down_impl(); - indent_impl(code_block) << "end;" << endl; + indent_impl(code_block) << "end;" << '\n'; // all required fields have been read? first = true; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if ((*f_iter)->get_req() == t_field::T_REQUIRED) { if(first) { - code_block << endl; + code_block << '\n'; first = false; } - indent_impl(code_block) << "if not " << prop_name(*f_iter, is_exception,"_req_isset_") << endl; + indent_impl(code_block) << "if not " << prop_name(*f_iter, is_exception,"_req_isset_") << '\n'; indent_impl(code_block) << "then raise TProtocolExceptionInvalidData.Create(" << "'required field " << prop_name(*f_iter, is_exception) << " not set');" - << endl; + << '\n'; } } - - if( is_exception && (!is_x_factory)) { - code_block << endl; - indent_impl(code_block) << "UpdateMessageProperty;" << endl; - } - indent_down_impl(); - indent_impl(code_block) << "end;" << endl << endl; - - string cls_nm; - - cls_nm = type_name(tstruct, true, is_exception && (!is_x_factory), is_x_factory, is_x_factory); - indent_impl(out) << "procedure " << cls_prefix << cls_nm << ".Read( const iprot: IProtocol);" - << endl; - indent_impl(out) << "var" << endl; - indent_up_impl(); - indent_impl(out) << "field_ : TThriftField;" << endl; - indent_impl(out) << "struc : TThriftStruct;" << endl; - indent_down_impl(); - out << local_vars.str() << endl; - out << code_block.str(); -} - -void t_delphi_generator::generate_delphi_struct_result_writer_impl(ostream& out, - string cls_prefix, - t_struct* tstruct, - bool is_exception, - bool is_x_factory) { - - ostringstream local_vars; - ostringstream code_block; - - string name = tstruct->get_name(); - const vector& fields = tstruct->get_sorted_members(); - vector::const_iterator f_iter; - - indent_impl(code_block) << "begin" << endl; - indent_up_impl(); - - indent_impl(local_vars) << "tracker : IProtocolRecursionTracker;" << endl; - indent_impl(code_block) << "tracker := oprot.NextRecursionLevel;" << endl; - - indent_impl(code_block) << "Thrift.Protocol.Init( struc, '" << name << "');" << endl; - indent_impl(code_block) << "oprot.WriteStructBegin(struc);" << endl; - - if (fields.size() > 0) { - indent_impl(code_block) << "Thrift.Protocol.Init( field_);" << endl; - for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { - indent_impl(code_block) << "if (" << prop_name(*f_iter, is_exception,"__isset_") << ") then" - << endl; - indent_impl(code_block) << "begin" << endl; - indent_up_impl(); - indent_impl(code_block) << "field_.Name := '" << (*f_iter)->get_name() << "';" << endl; - indent_impl(code_block) << "field_.Type_ := " << type_to_enum((*f_iter)->get_type()) << ";" - << endl; - indent_impl(code_block) << "field_.ID := " << (*f_iter)->get_key() << ";" << endl; - indent_impl(code_block) << "oprot.WriteFieldBegin(field_);" << endl; - generate_serialize_field(code_block, is_exception, *f_iter, "Self.", local_vars); - indent_impl(code_block) << "oprot.WriteFieldEnd();" << endl; - indent_down_impl(); - } + if( is_exception) { + code_block << '\n'; + indent_impl(code_block) << "UpdateMessageProperty;" << '\n'; } - - indent_impl(code_block) << "oprot.WriteFieldStop();" << endl; - indent_impl(code_block) << "oprot.WriteStructEnd();" << endl; - indent_down_impl(); - indent_impl(code_block) << "end;" << endl << endl; + indent_impl(code_block) << "end;" << '\n' << '\n'; string cls_nm; - cls_nm = type_name(tstruct, true, is_exception && (!is_x_factory), is_x_factory, is_x_factory); + cls_nm = type_name(tstruct, true, is_exception); - indent_impl(out) << "procedure " << cls_prefix << cls_nm << ".Write( const oprot: IProtocol);" - << endl; - indent_impl(out) << "var" << endl; + indent_impl(out) << "procedure " << cls_prefix << cls_nm << ".Read( const iprot: IProtocol);" << '\n'; + indent_impl(out) << "var" << '\n'; indent_up_impl(); - indent_impl(out) << "struc : TThriftStruct;" << endl; - - if (fields.size() > 0) { - indent_impl(out) << "field_ : TThriftField;" << endl; - } - - out << local_vars.str(); + indent_impl(out) << "field_ : TThriftField;" << '\n'; + indent_impl(out) << "struc : TThriftStruct;" << '\n'; indent_down_impl(); + out << local_vars.str() << '\n'; out << code_block.str(); } void t_delphi_generator::generate_delphi_struct_writer_impl(ostream& out, string cls_prefix, t_struct* tstruct, - bool is_exception, - bool is_x_factory) { + bool is_exception) { ostringstream local_vars; ostringstream code_block; @@ -3849,17 +3690,17 @@ void t_delphi_generator::generate_delphi_struct_writer_impl(ostream& out, const vector& fields = tstruct->get_sorted_members(); vector::const_iterator f_iter; - indent_impl(code_block) << "begin" << endl; + indent_impl(code_block) << "begin" << '\n'; indent_up_impl(); - indent_impl(local_vars) << "tracker : IProtocolRecursionTracker;" << endl; - indent_impl(code_block) << "tracker := oprot.NextRecursionLevel;" << endl; + indent_impl(local_vars) << "tracker : IProtocolRecursionTracker;" << '\n'; + indent_impl(code_block) << "tracker := oprot.NextRecursionLevel;" << '\n'; - indent_impl(code_block) << "Thrift.Protocol.Init( struc, '" << name << "');" << endl; - indent_impl(code_block) << "oprot.WriteStructBegin(struc);" << endl; + indent_impl(code_block) << "Thrift.Protocol.Init( struc, '" << name << "');" << '\n'; + indent_impl(code_block) << "oprot.WriteStructBegin(struc);" << '\n'; if (fields.size() > 0) { - indent_impl(code_block) << "Thrift.Protocol.Init( field_);" << endl; + indent_impl(code_block) << "Thrift.Protocol.Init( field_);" << '\n'; } for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { @@ -3870,54 +3711,54 @@ void t_delphi_generator::generate_delphi_struct_writer_impl(ostream& out, bool has_isset = (!is_required); if (is_required && null_allowed) { null_allowed = false; - indent_impl(code_block) << "if (Self." << fieldname << " = nil)" << endl; + indent_impl(code_block) << "if (Self." << fieldname << " = nil)" << '\n'; indent_impl(code_block) << "then raise TProtocolExceptionInvalidData.Create(" << "'required field " << fieldname << " not set');" - << endl; + << '\n'; } if (null_allowed) { indent_impl(code_block) << "if (Self." << fieldname << " <> nil)"; if (has_isset) { code_block << " and " << isset_name; } - code_block << " then begin" << endl; + code_block << " then begin" << '\n'; indent_up_impl(); } else { if (has_isset) { - indent_impl(code_block) << "if (" << isset_name << ") then begin" << endl; + indent_impl(code_block) << "if (" << isset_name << ") then begin" << '\n'; indent_up_impl(); } } - indent_impl(code_block) << "field_.Name := '" << (*f_iter)->get_name() << "';" << endl; + indent_impl(code_block) << "field_.Name := '" << (*f_iter)->get_name() << "';" << '\n'; indent_impl(code_block) << "field_.Type_ := " << type_to_enum((*f_iter)->get_type()) << ";" - << endl; - indent_impl(code_block) << "field_.ID := " << (*f_iter)->get_key() << ";" << endl; - indent_impl(code_block) << "oprot.WriteFieldBegin(field_);" << endl; + << '\n'; + indent_impl(code_block) << "field_.ID := " << (*f_iter)->get_key() << ";" << '\n'; + indent_impl(code_block) << "oprot.WriteFieldBegin(field_);" << '\n'; generate_serialize_field(code_block, is_exception, *f_iter, "Self.", local_vars); - indent_impl(code_block) << "oprot.WriteFieldEnd();" << endl; + indent_impl(code_block) << "oprot.WriteFieldEnd();" << '\n'; if (null_allowed || has_isset) { indent_down_impl(); - indent_impl(code_block) << "end;" << endl; + indent_impl(code_block) << "end;" << '\n'; } } - indent_impl(code_block) << "oprot.WriteFieldStop();" << endl; - indent_impl(code_block) << "oprot.WriteStructEnd();" << endl; + indent_impl(code_block) << "oprot.WriteFieldStop();" << '\n'; + indent_impl(code_block) << "oprot.WriteStructEnd();" << '\n'; indent_down_impl(); - indent_impl(code_block) << "end;" << endl << endl; + indent_impl(code_block) << "end;" << '\n' << '\n'; string cls_nm; - cls_nm = type_name(tstruct, true, is_exception && (!is_x_factory), is_x_factory, is_x_factory); + cls_nm = type_name(tstruct, true, is_exception); indent_impl(out) << "procedure " << cls_prefix << cls_nm << ".Write( const oprot: IProtocol);" - << endl; - indent_impl(out) << "var" << endl; + << '\n'; + indent_impl(out) << "var" << '\n'; indent_up_impl(); - indent_impl(out) << "struc : TThriftStruct;" << endl; + indent_impl(out) << "struc : TThriftStruct;" << '\n'; if (fields.size() > 0) { - indent_impl(out) << "field_ : TThriftField;" << endl; + indent_impl(out) << "field_ : TThriftField;" << '\n'; } out << local_vars.str(); indent_down_impl(); @@ -3927,8 +3768,7 @@ void t_delphi_generator::generate_delphi_struct_writer_impl(ostream& out, void t_delphi_generator::generate_delphi_struct_tostring_impl(ostream& out, string cls_prefix, t_struct* tstruct, - bool is_exception, - bool is_x_factory) { + bool is_exception) { const vector& fields = tstruct->get_members(); vector::const_iterator f_iter; @@ -3936,7 +3776,7 @@ void t_delphi_generator::generate_delphi_struct_tostring_impl(ostream& out, string cls_nm; if (is_exception) { - cls_nm = type_name(tstruct, true, (!is_x_factory), is_x_factory, true); + cls_nm = type_name(tstruct, true, true/*, false, true*/); } else { cls_nm = type_name(tstruct, true, false); } @@ -3945,28 +3785,28 @@ void t_delphi_generator::generate_delphi_struct_tostring_impl(ostream& out, string tmp_first = tmp("_first"); bool useFirstFlag = false; - indent_impl(out) << "function " << cls_prefix << cls_nm << ".ToString: string;" << endl; - indent_impl(out) << "var" << endl; + indent_impl(out) << "function " << cls_prefix << cls_nm << ".ToString: string;" << '\n'; + indent_impl(out) << "var" << '\n'; indent_up_impl(); - indent_impl(out) << tmp_sb << " : TThriftStringBuilder;" << endl; + indent_impl(out) << tmp_sb << " : TThriftStringBuilder;" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { bool is_optional = ((*f_iter)->get_req() != t_field::T_REQUIRED); if (is_optional) { - indent_impl(out) << tmp_first << " : System.Boolean;" << endl; + indent_impl(out) << tmp_first << " : System.Boolean;" << '\n'; useFirstFlag = true; } break; } indent_down_impl(); - indent_impl(out) << "begin" << endl; + indent_impl(out) << "begin" << '\n'; indent_up_impl(); - indent_impl(out) << tmp_sb << " := TThriftStringBuilder.Create('(');" << endl; - indent_impl(out) << "try" << endl; + indent_impl(out) << tmp_sb << " := TThriftStringBuilder.Create('(');" << '\n'; + indent_impl(out) << "try" << '\n'; indent_up_impl(); if (useFirstFlag) { - indent_impl(out) << tmp_first << " := TRUE;" << endl; + indent_impl(out) << tmp_first << " := TRUE;" << '\n'; } bool had_required = false; // set to true after first required field has been processed @@ -3979,53 +3819,50 @@ void t_delphi_generator::generate_delphi_struct_tostring_impl(ostream& out, if (is_optional) { out << " and " << prop_name(*f_iter, is_exception,"__isset_"); } - out << " then begin" << endl; + out << " then begin" << '\n'; indent_up_impl(); } else { if (is_optional) { indent_impl(out) << "if (" << prop_name(*f_iter, is_exception, "__isset_") << ") then begin" - << endl; + << '\n'; indent_up_impl(); } } if (useFirstFlag && (!had_required)) { - indent_impl(out) << "if not " << tmp_first << " then " << tmp_sb << ".Append(',');" << endl; + indent_impl(out) << "if not " << tmp_first << " then " << tmp_sb << ".Append(',');" << '\n'; if (is_optional) { - indent_impl(out) << tmp_first << " := FALSE;" << endl; + indent_impl(out) << tmp_first << " := FALSE;" << '\n'; } indent_impl(out) << tmp_sb << ".Append('" << prop_name((*f_iter), is_exception) << ": ');" - << endl; + << '\n'; } else { indent_impl(out) << tmp_sb << ".Append(', " << prop_name((*f_iter), is_exception) << ": ');" - << endl; + << '\n'; } - t_type* ttype = (*f_iter)->get_type(); - while (ttype->is_typedef()) { - ttype = ((t_typedef*)ttype)->get_type(); - } + t_type* ttype = (*f_iter)->get_type()->get_true_type(); if (ttype->is_xception() || ttype->is_struct()) { indent_impl(out) << "if (Self." << prop_name((*f_iter), is_exception) << " = nil) then " << tmp_sb << ".Append('') else " << tmp_sb << ".Append( Self." - << prop_name((*f_iter), is_exception) << ".ToString());" << endl; + << prop_name((*f_iter), is_exception) << ".ToString());" << '\n'; } else if (ttype->is_enum()) { - 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; + indent_impl(out) << tmp_sb << ".Append(EnumUtils<" + << type_name(ttype, false, true) + << ">.ToString( System.Ord( Self." + << prop_name((*f_iter), is_exception) << ")));" << '\n'; } else if (ttype->is_uuid()) { indent_impl(out) << tmp_sb << ".Append( GUIDToString(Self." << prop_name((*f_iter), is_exception) << "));" - << endl; + << '\n'; } else { indent_impl(out) << tmp_sb << ".Append( Self." << prop_name((*f_iter), is_exception) << ");" - << endl; + << '\n'; } if (null_allowed || is_optional) { indent_down_impl(); - indent_impl(out) << "end;" << endl; + indent_impl(out) << "end;" << '\n'; } if (!is_optional) { @@ -4033,27 +3870,25 @@ void t_delphi_generator::generate_delphi_struct_tostring_impl(ostream& out, } } - indent_impl(out) << tmp_sb << ".Append(')');" << endl; - indent_impl(out) << "Result := " << tmp_sb << ".ToString;" << endl; + indent_impl(out) << tmp_sb << ".Append(')');" << '\n'; + indent_impl(out) << "Result := " << tmp_sb << ".ToString;" << '\n'; if (useFirstFlag) { - indent_impl(out) << "if " << tmp_first << " then {prevent warning};" << endl; + indent_impl(out) << "if " << tmp_first << " then {prevent warning};" << '\n'; } indent_down_impl(); - indent_impl(out) << "finally" << endl; + indent_impl(out) << "finally" << '\n'; indent_up_impl(); - indent_impl(out) << tmp_sb << ".Free;" << endl; + indent_impl(out) << tmp_sb << ".Free;" << '\n'; indent_down_impl(); - indent_impl(out) << "end;" << endl; + indent_impl(out) << "end;" << '\n'; indent_down_impl(); - indent_impl(out) << "end;" << endl << endl; + indent_impl(out) << "end;" << '\n' << '\n'; } bool t_delphi_generator::is_void(t_type* type) { - while (type->is_typedef()) { - type = ((t_typedef*)type)->get_type(); - } + type = type->get_true_type(); if (type->is_base_type()) { t_base_type::t_base tbase = ((t_base_type*)type)->get_base(); @@ -4069,10 +3904,36 @@ std::string t_delphi_generator::display_name() const { } +bool t_delphi_generator::is_deprecated(std::map>& annotations) +{ + auto iter = annotations.find("deprecated"); + return (annotations.end() != iter); +} + +std::string t_delphi_generator::render_deprecation_attribute(std::map>& annotations, std::string prefix, std::string postfix) +{ + std::string result = ""; + auto iter = annotations.find("deprecated"); + if( annotations.end() != iter) { + result += prefix; + result += "deprecated"; + + // empty annotation values end up with "1" somewhere, ignore these as well + if ((iter->second.back().length() > 0) && (iter->second.back() != "1")) { + result += " " + make_pascal_string_literal(iter->second.back()); + } + + result += postfix; + } + return result; +} + + + + THRIFT_REGISTER_GENERATOR( delphi, "Delphi", - " ansistr_binary: Use AnsiString for binary datatype (default is TBytes).\n" " register_types: Enable TypeRegistry, allows for creation of struct, union\n" " and container instances by interface or TypeInfo()\n" " constprefix: Name TConstants classes after IDL to reduce ambiguities\n" diff --git a/compiler/cpp/src/thrift/generate/t_erl_generator.cc b/compiler/cpp/src/thrift/generate/t_erl_generator.cc index fdbad196339..e618e8eb4b3 100644 --- a/compiler/cpp/src/thrift/generate/t_erl_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_erl_generator.cc @@ -39,7 +39,15 @@ using std::string; using std::stringstream; using std::vector; -static const std::string endl = "\n"; // avoid ostream << std::endl flushes +/** + * Helper enum for string mapping + */ +enum class StringTo {String, Binary, Both}; + +/** + * Helper enum for sets mapping + */ +enum class SetsTo {V1, V2}; /** * Erlang code generator. @@ -60,6 +68,8 @@ class t_erl_generator : public t_generator { maps_ = false; export_lines_first_ = true; export_types_lines_first_ = true; + string_to_ = StringTo::Both; + sets_to_ = SetsTo::V1; for( iter = parsed_options.begin(); iter != parsed_options.end(); ++iter) { if( iter->first.compare("legacynames") == 0) { @@ -70,6 +80,26 @@ class t_erl_generator : public t_generator { delimiter_ = iter->second; } else if( iter->first.compare("app_prefix") == 0) { app_prefix_ = iter->second; + } else if( iter->first.compare("string") == 0) { + auto string_to_value = iter->second; + if( string_to_value.compare("string") == 0) { + string_to_ = StringTo::String; + } else if( string_to_value.compare("binary") == 0) { + string_to_ = StringTo::Binary; + } else if( string_to_value.compare("both") == 0) { + string_to_ = StringTo::Both; + } else { + throw "unknown string option value:" + string_to_value; + } + } else if( iter->first.compare("set") == 0) { + auto set_to_value = iter->second; + if( set_to_value.compare("v1") == 0) { + sets_to_ = SetsTo::V1; + } else if( set_to_value.compare("v2") == 0) { + sets_to_ = SetsTo::V2; + } else { + throw "unknown set option value:" + set_to_value; + } } else { throw "unknown option erl:" + iter->first; } @@ -102,11 +132,13 @@ class t_erl_generator : public t_generator { std::string render_member_type(t_field* field); std::string render_member_value(t_field* field); std::string render_member_requiredness(t_field* field); + std::string render_string_type(); // std::string render_default_value(t_type* type); std::string render_default_value(t_field* field); std::string render_const_value(t_type* type, t_const_value* value); std::string render_type_term(t_type* ttype, bool expand_structs, bool extended_info = false); + std::string render_default_sets_value(); /** * Struct generation code @@ -142,6 +174,7 @@ class t_erl_generator : public t_generator { std::string render_includes(); std::string type_name(t_type* ttype); std::string render_const_list_values(t_type* type, t_const_value* value); + std::string render_const_string_value(t_const_value* value); std::string function_signature(t_function* tfunction, std::string prefix = ""); @@ -190,6 +223,12 @@ class t_erl_generator : public t_generator { /* used to avoid module name clashes for different applications */ std::string app_prefix_; + /* string type definition strategy */ + StringTo string_to_; + + /* sets type definition strategy */ + SetsTo sets_to_; + /** * add function to export list */ @@ -268,14 +307,14 @@ void t_erl_generator::init_generator() { hrl_header(f_types_hrl_file_, program_module_name + "_types"); - f_types_file_ << erl_autogen_comment() << endl - << "-module(" << program_module_name << "_types)." << endl - << erl_imports() << endl; + f_types_file_ << erl_autogen_comment() << '\n' + << "-module(" << program_module_name << "_types)." << '\n' + << erl_imports() << '\n'; - f_types_file_ << "-include(\"" << program_module_name << "_types.hrl\")." << endl - << endl; + f_types_file_ << "-include(\"" << program_module_name << "_types.hrl\")." << '\n' + << '\n'; - f_types_hrl_file_ << render_includes() << endl; + f_types_hrl_file_ << render_includes() << '\n'; // consts files string f_consts_name = get_out_dir() + program_module_name + "_constants.erl"; @@ -284,28 +323,28 @@ void t_erl_generator::init_generator() { f_consts_file_.open(f_consts_name.c_str()); f_consts_hrl_file_.open(f_consts_hrl_name.c_str()); - f_consts_file_ << erl_autogen_comment() << endl - << "-module(" << program_module_name << "_constants)." << endl - << erl_imports() << endl - << "-include(\"" << program_module_name << "_types.hrl\")." << endl - << endl; + f_consts_file_ << erl_autogen_comment() << '\n' + << "-module(" << program_module_name << "_constants)." << '\n' + << erl_imports() << '\n' + << "-include(\"" << program_module_name << "_types.hrl\")." << '\n' + << '\n'; - f_consts_hrl_file_ << erl_autogen_comment() << endl << erl_imports() << endl - << "-include(\"" << program_module_name << "_types.hrl\")." << endl << endl; + f_consts_hrl_file_ << erl_autogen_comment() << '\n' << erl_imports() << '\n' + << "-include(\"" << program_module_name << "_types.hrl\")." << '\n' << '\n'; } /** * Boilerplate at beginning and end of header files */ void t_erl_generator::hrl_header(ostream& out, string name) { - out << erl_autogen_comment() << endl - << "-ifndef(_" << name << "_included)." << endl << "-define(_" << name << "_included, yeah)." - << endl; + out << erl_autogen_comment() << '\n' + << "-ifndef(_" << name << "_included)." << '\n' << "-define(_" << name << "_included, yeah)." + << '\n'; } void t_erl_generator::hrl_footer(ostream& out, string name) { (void)name; - out << "-endif." << endl; + out << "-endif." << '\n'; } /** @@ -365,13 +404,13 @@ void t_erl_generator::close_generator() { export_types_string("struct_names", 0); export_types_string("exception_names", 0); - f_types_file_ << "-export([" << export_types_lines_.str() << "])." << endl << endl; + f_types_file_ << "-export([" << export_types_lines_.str() << "])." << '\n' << '\n'; f_types_file_ << f_info_.str(); - f_types_file_ << "struct_info(_) -> erlang:error(function_clause)." << endl << endl; + f_types_file_ << "struct_info(_) -> erlang:error(function_clause)." << '\n' << '\n'; f_types_file_ << f_info_ext_.str(); - f_types_file_ << "struct_info_ext(_) -> erlang:error(function_clause)." << endl << endl; + f_types_file_ << "struct_info_ext(_) -> erlang:error(function_clause)." << '\n' << '\n'; generate_const_functions(); @@ -527,10 +566,10 @@ void t_erl_generator::generate_enum(t_enum* tenum) { string name = (*c_iter)->get_name(); indent(f_types_hrl_file_) << "-define(" << constify(make_safe_for_module_name(program_name_)) << "_" << constify(tenum->get_name()) << "_" << constify(name) << ", " - << value << ")." << endl; + << value << ")." << '\n'; } - f_types_hrl_file_ << endl; + f_types_hrl_file_ << '\n'; } void t_erl_generator::generate_enum_info(t_enum* tenum){ @@ -551,7 +590,7 @@ void t_erl_generator::generate_enum_info(t_enum* tenum){ } indent_down(); } - f_types_file_ << "\n"; + f_types_file_ << '\n'; indent(f_types_file_) << "];\n\n"; indent_down(); } @@ -579,7 +618,7 @@ void t_erl_generator::generate_const(t_const* tconst) { v_consts_.push_back(tconst); f_consts_hrl_file_ << "-define(" << constify(make_safe_for_module_name(program_name_)) << "_" - << constify(name) << ", " << render_const_value(type, value) << ")." << endl << endl; + << constify(name) << ", " << render_const_value(type, value) << ")." << '\n' << '\n'; } /** @@ -595,7 +634,7 @@ string t_erl_generator::render_const_value(t_type* type, t_const_value* value) { t_base_type::t_base tbase = ((t_base_type*)type)->get_base(); switch (tbase) { case t_base_type::TYPE_STRING: - out << '"' << get_escaped_string(value) << '"'; + out << render_const_string_value(value); break; case t_base_type::TYPE_BOOL: out << (value->get_integer() > 0 ? "true" : "false"); @@ -678,7 +717,11 @@ string t_erl_generator::render_const_value(t_type* type, t_const_value* value) { out << ","; } } - out << "])"; + out << "]"; + if (sets_to_ == SetsTo::V2) { + out << ", [{version, 2}]"; + } + out << ")"; } else if (type->is_list()) { out << "[" << render_const_list_values(type, value) << "]"; } else { @@ -705,6 +748,13 @@ string t_erl_generator::render_const_list_values(t_type* type, t_const_value* va return out.str(); } +string t_erl_generator::render_const_string_value(t_const_value* constval) { + if (string_to_ == StringTo::Binary) { + return "<<\"" + get_escaped_string(constval) + "\">>"; + } + return '"' + get_escaped_string(constval) + '"'; +} + string t_erl_generator::render_default_value(t_field* field) { t_type* type = field->get_type(); @@ -717,7 +767,7 @@ string t_erl_generator::render_default_value(t_field* field) { return "dict:new()"; } } else if (type->is_set()) { - return "sets:new()"; + return render_default_sets_value(); } else if (type->is_list()) { return "[]"; } else { @@ -725,13 +775,24 @@ string t_erl_generator::render_default_value(t_field* field) { } } +string t_erl_generator::render_default_sets_value() { + switch (sets_to_) { + case SetsTo::V1: + return "sets:new()"; + case SetsTo::V2: + return "sets:new([{version,2}])"; + default: + throw "compiler error: unsupported set type"; + } +} + string t_erl_generator::render_member_type(t_field* field) { t_type* type = get_true_type(field->get_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_STRING: - return "string() | binary()"; + return render_string_type(); case t_base_type::TYPE_BOOL: return "boolean()"; case t_base_type::TYPE_I8: @@ -763,6 +824,19 @@ string t_erl_generator::render_member_type(t_field* field) { } } +string t_erl_generator::render_string_type() { + switch (string_to_) { + case StringTo::String: + return "string()"; + case StringTo::Binary: + return "binary()"; + case StringTo::Both: + return "string() | binary()"; + default: + throw "compiler error: unsupported string type"; + } +} + string t_erl_generator::render_member_requiredness(t_field* field) { switch (field->get_req()) { case t_field::T_REQUIRED: @@ -809,7 +883,13 @@ void t_erl_generator::generate_erl_struct(t_struct* tstruct, bool is_exception) * @param tstruct The struct definition */ void t_erl_generator::generate_erl_struct_definition(ostream& out, t_struct* tstruct) { - indent(out) << "%% struct " << type_name(tstruct) << endl << endl; + indent(out) << "%% "; + if (tstruct->is_union()) { + out << "union "; + } else { + out << "struct "; + } + out << type_name(tstruct) << '\n' << '\n'; std::stringstream buf; buf << indent() << "-record(" << type_name(tstruct) << ", {"; @@ -819,13 +899,13 @@ void t_erl_generator::generate_erl_struct_definition(ostream& out, t_struct* tst for (vector::const_iterator m_iter = members.begin(); m_iter != members.end();) { generate_erl_struct_member(buf, *m_iter); if (++m_iter != members.end()) { - buf << "," << endl << field_indent; + buf << "," << '\n' << field_indent; } } buf << "})."; - out << buf.str() << endl; - out << "-type " + type_name(tstruct) << "() :: #" + type_name(tstruct) + "{}." << endl << endl; + out << buf.str() << '\n'; + out << "-type " + type_name(tstruct) << "() :: #" + type_name(tstruct) + "{}." << '\n' << '\n'; } /** @@ -871,19 +951,19 @@ string t_erl_generator::render_member_value(t_field* field) { * Generates the read method for a struct */ void t_erl_generator::generate_erl_struct_info(ostream& out, t_struct* tstruct) { - indent(out) << "struct_info(" << type_name(tstruct) << ") ->" << endl; + indent(out) << "struct_info(" << type_name(tstruct) << ") ->" << '\n'; indent_up(); - out << indent() << render_type_term(tstruct, true) << ";" << endl; + out << indent() << render_type_term(tstruct, true) << ";" << '\n'; indent_down(); - out << endl; + out << '\n'; } void t_erl_generator::generate_erl_extended_struct_info(ostream& out, t_struct* tstruct) { - indent(out) << "struct_info_ext(" << type_name(tstruct) << ") ->" << endl; + indent(out) << "struct_info_ext(" << type_name(tstruct) << ") ->" << '\n'; indent_up(); - out << indent() << render_type_term(tstruct, true, true) << ";" << endl; + out << indent() << render_type_term(tstruct, true, true) << ";" << '\n'; indent_down(); - out << endl; + out << '\n'; } /** @@ -909,11 +989,11 @@ void t_erl_generator::generate_service(t_service* tservice) { if (tservice->get_extends() != nullptr) { f_service_hrl_ << "-include(\"" << make_safe_for_module_name(tservice->get_extends()->get_name()) - << "_thrift.hrl\"). % inherit " << endl; + << "_thrift.hrl\"). % inherit " << '\n'; } f_service_hrl_ << "-include(\"" << make_safe_for_module_name(program_name_) << "_types.hrl\")." - << endl << endl; + << '\n' << '\n'; // Generate the three main parts of the service (well, two for now in PHP) generate_service_helpers(tservice); // cpiro: New Erlang Order @@ -924,13 +1004,13 @@ void t_erl_generator::generate_service(t_service* tservice) { // indent_down(); - f_service_file_ << erl_autogen_comment() << endl << "-module(" << service_name_ << "_thrift)." - << endl << "-behaviour(thrift_service)." << endl << endl << erl_imports() << endl; + f_service_file_ << erl_autogen_comment() << '\n' << "-module(" << service_name_ << "_thrift)." + << '\n' << "-behaviour(thrift_service)." << '\n' << '\n' << erl_imports() << '\n'; f_service_file_ << "-include(\"" << make_safe_for_module_name(tservice->get_name()) - << "_thrift.hrl\")." << endl << endl; + << "_thrift.hrl\")." << '\n' << '\n'; - f_service_file_ << "-export([" << export_lines_.str() << "])." << endl << endl; + f_service_file_ << "-export([" << export_lines_.str() << "])." << '\n' << '\n'; f_service_file_ << f_service_.str(); @@ -946,7 +1026,7 @@ void t_erl_generator::generate_service_metadata(t_service* tservice) { vector functions = tservice->get_functions(); size_t num_functions = functions.size(); - indent(f_service_) << "function_names() -> " << endl; + indent(f_service_) << "function_names() -> " << '\n'; indent_up(); indent(f_service_) << "["; @@ -972,14 +1052,14 @@ void t_erl_generator::generate_service_helpers(t_service* tservice) { vector::iterator f_iter; // indent(f_service_) << - // "% HELPER FUNCTIONS AND STRUCTURES" << endl << endl; + // "% HELPER FUNCTIONS AND STRUCTURES" << '\n' << '\n'; export_string("struct_info", 1); for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { generate_erl_function_helpers(*f_iter); } - f_service_ << "struct_info(_) -> erlang:error(function_clause)." << endl; + f_service_ << "struct_info(_) -> erlang:error(function_clause)." << '\n'; } /** @@ -1002,26 +1082,26 @@ void t_erl_generator::generate_service_interface(t_service* tservice) { vector functions = tservice->get_functions(); vector::iterator f_iter; - f_service_ << "%%% interface" << endl; + f_service_ << "%%% interface" << '\n'; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { - f_service_ << indent() << "% " << function_signature(*f_iter) << endl; + f_service_ << indent() << "% " << function_signature(*f_iter) << '\n'; generate_function_info(tservice, *f_iter); } // Inheritance - pass unknown functions to base class if (tservice->get_extends() != nullptr) { - indent(f_service_) << "function_info(Function, InfoType) ->" << endl; + indent(f_service_) << "function_info(Function, InfoType) ->" << '\n'; indent_up(); indent(f_service_) << make_safe_for_module_name(tservice->get_extends()->get_name()) - << "_thrift:function_info(Function, InfoType)." << endl; + << "_thrift:function_info(Function, InfoType)." << '\n'; indent_down(); } else { // return function_clause error for non-existent functions - indent(f_service_) << "function_info(_Func, _Info) -> erlang:error(function_clause)." << endl; + indent(f_service_) << "function_info(_Func, _Info) -> erlang:error(function_clause)." << '\n'; } - indent(f_service_) << endl; + indent(f_service_) << '\n'; } /** @@ -1036,30 +1116,30 @@ void t_erl_generator::generate_function_info(t_service* tservice, t_function* tf t_struct* arg_struct = tfunction->get_arglist(); // function_info(Function, params_type): - indent(f_service_) << "function_info(" << name_atom << ", params_type) ->" << endl; + indent(f_service_) << "function_info(" << name_atom << ", params_type) ->" << '\n'; indent_up(); - indent(f_service_) << render_type_term(arg_struct, true) << ";" << endl; + indent(f_service_) << render_type_term(arg_struct, true) << ";" << '\n'; indent_down(); // function_info(Function, reply_type): - indent(f_service_) << "function_info(" << name_atom << ", reply_type) ->" << endl; + indent(f_service_) << "function_info(" << name_atom << ", reply_type) ->" << '\n'; indent_up(); if (!tfunction->get_returntype()->is_void()) - indent(f_service_) << render_type_term(tfunction->get_returntype(), false) << ";" << endl; + indent(f_service_) << render_type_term(tfunction->get_returntype(), false) << ";" << '\n'; else if (tfunction->is_oneway()) - indent(f_service_) << "oneway_void;" << endl; + indent(f_service_) << "oneway_void;" << '\n'; else indent(f_service_) << "{struct, []}" - << ";" << endl; + << ";" << '\n'; indent_down(); // function_info(Function, exceptions): - indent(f_service_) << "function_info(" << name_atom << ", exceptions) ->" << endl; + indent(f_service_) << "function_info(" << name_atom << ", exceptions) ->" << '\n'; indent_up(); - indent(f_service_) << render_type_term(xs, true) << ";" << endl; + indent(f_service_) << render_type_term(xs, true) << ";" << '\n'; indent_down(); } @@ -1246,11 +1326,11 @@ std::string t_erl_generator::render_type_term(t_type* type, } if (++i != end) { - buf << "," << endl << field_indent; + buf << "," << '\n' << field_indent; } } - buf << "]}" << endl; + buf << "]}" << '\n'; return buf.str(); } else { return "{struct, {" + atomify(type_module(type)) + ", " + type_name(type) + "}}"; @@ -1292,4 +1372,6 @@ THRIFT_REGISTER_GENERATOR( " legacynames: Output files retain naming conventions of Thrift 0.9.1 and earlier.\n" " delimiter= Delimiter between namespace prefix and record name. Default is '.'.\n" " app_prefix= Application prefix for generated Erlang files.\n" - " maps: Generate maps instead of dicts.\n") + " maps: Generate maps instead of dicts.\n" + " string= Define string as 'string', 'binary' or 'both'. Default is 'both'.\n" + " set= Define sets implementation, supported 'v1' and 'v2'. Default is 'v1'.\n") diff --git a/compiler/cpp/src/thrift/generate/t_generator.cc b/compiler/cpp/src/thrift/generate/t_generator.cc index 970281e74cf..217cf8ab9ec 100644 --- a/compiler/cpp/src/thrift/generate/t_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_generator.cc @@ -77,8 +77,8 @@ void t_generator::generate_program() { } std::set t_generator::lang_keywords_for_validation() const { - // Nothing by default. It makes no sense to restrict the whole world to use non-PHP keywords only. - // Override on a per-generator(!) basis if you cannot live without it, e.g. that particular language has no + // Nothing by default. It makes no sense to restrict the whole world to use non-PHP keywords only. + // Override on a per-generator(!) basis if you cannot live without it, e.g. that particular language has no // mechanism or way to deal with it properly, so we absolutely need to fail on it as the last possible resort. return {}; } @@ -101,35 +101,43 @@ void t_generator::validate(const vector& list) const{ void t_generator::validate(t_function const* f) const { validate_id(f->get_name()); + f->validate(); validate(f->get_arglist()); validate(f->get_xceptions()); } void t_generator::validate(t_service const* s) const { validate_id(s->get_name()); + s->validate(); validate(s->get_functions()); } void t_generator::validate(t_enum const* en) const { validate_id(en->get_name()); + en->validate(); validate(en->get_constants()); } void t_generator::validate(t_struct const* s) const { validate_id(s->get_name()); + s->validate(); validate(s->get_members()); } void t_generator::validate(t_enum_value const* en_val) const { validate_id(en_val->get_name()); + en_val->validate(); } void t_generator::validate(t_typedef const* td) const { validate_id(td->get_name()); + td->validate(); } void t_generator::validate(t_const const* c) const { validate_id(c->get_name()); + c->validate(); } void t_generator::validate(t_field const* f) const { validate_id(f->get_name()); + f->validate(); } void t_generator::validate_id(const string& id) const { @@ -172,11 +180,11 @@ void t_generator::generate_docstring_comment(ostream& out, docs.getline(line, 1024); if (strlen(line) > 0) { - indent(out) << line_prefix << line << std::endl; + indent(out) << line_prefix << line << '\n'; } else if (line_prefix.empty()){ - out << std::endl; + out << '\n'; } else if(!docs.eof()) { - indent(out) << line_prefix << std::endl; + indent(out) << line_prefix << '\n'; } } if (!comment_end.empty()) diff --git a/compiler/cpp/src/thrift/generate/t_go_generator.cc b/compiler/cpp/src/thrift/generate/t_go_generator.cc index db30c8bae8c..8d0589231cd 100644 --- a/compiler/cpp/src/thrift/generate/t_go_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_go_generator.cc @@ -518,7 +518,7 @@ void t_go_generator::init_generator() { f_consts_ << go_autogen_comment() << go_package() << render_includes(true); - f_const_values_ << endl << "func init() {" << endl; + f_const_values_ << '\n' << "func init() {" << '\n'; // Create file for the GoUnusedProtection__ variable string f_unused_prot_name_ = package_dir_ + "/" + "GoUnusedProtection__.go"; @@ -706,6 +706,7 @@ string t_go_generator::go_imports_begin(bool consts) { } system_packages.push_back("errors"); system_packages.push_back("fmt"); + system_packages.push_back("iter"); system_packages.push_back("log/slog"); system_packages.push_back("time"); // For the thrift import, always do rename import to make sure it's called thrift. @@ -731,6 +732,7 @@ string t_go_generator::go_imports_end() { "var _ = context.Background\n" "var _ = errors.New\n" "var _ = fmt.Printf\n" + "var _ = iter.Pull[int]\n" "var _ = slog.Log\n" "var _ = time.Now\n" "var _ = thrift.ZERO\n" @@ -744,7 +746,7 @@ string t_go_generator::go_imports_end() { * Closes the type files */ void t_go_generator::close_generator() { - f_const_values_ << "}" << endl << endl; + f_const_values_ << "}" << '\n' << '\n'; f_consts_ << f_const_values_.str(); // Close types and constants files @@ -768,11 +770,13 @@ void t_go_generator::generate_typedef(t_typedef* ttypedef) { return; } - f_types_ << "type " << new_type_name << " " << base_type << endl << endl; + generate_deprecation_comment(f_types_, ttypedef->annotations_); + f_types_ << "type " << new_type_name << " " << base_type << '\n' << '\n'; // Generate a convenience function that converts an instance of a type // (which may be a constant) into a pointer to an instance of a type. + generate_deprecation_comment(f_types_, ttypedef->annotations_); f_types_ << "func " << new_type_name << "Ptr(v " << new_type_name << ") *" << new_type_name - << " { return &v }" << endl << endl; + << " { return &v }" << '\n' << '\n'; } /** @@ -782,90 +786,142 @@ void t_go_generator::generate_typedef(t_typedef* ttypedef) { * @param tenum The enumeration */ void t_go_generator::generate_enum(t_enum* tenum) { - std::ostringstream to_string_mapping, from_string_mapping; + std::ostringstream to_string_mapping, from_string_mapping, known_values_mapping; std::string tenum_name(publicize(tenum->get_name())); generate_go_docstring(f_types_, tenum); - f_types_ << "type " << tenum_name << " int64" << endl << "const (" << endl; + generate_deprecation_comment(f_types_, tenum->annotations_); + f_types_ << "type " << tenum_name << " int64" << '\n' << '\n' << "const (" << '\n'; - to_string_mapping << indent() << "func (p " << tenum_name << ") String() string {" << endl; - to_string_mapping << indent() << " switch p {" << endl; + known_values_mapping << indent() << "var known" << tenum_name << "Values" << " = []" << tenum_name << "{" << '\n'; + to_string_mapping << indent() << "func (p " << tenum_name << ") String() string {" << '\n'; + indent_up(); + to_string_mapping << indent() << "switch p {" << '\n'; + indent_down(); + + generate_deprecation_comment(from_string_mapping, tenum->annotations_); from_string_mapping << indent() << "func " << tenum_name << "FromString(s string) (" << tenum_name - << ", error) {" << endl; - from_string_mapping << indent() << " switch s {" << endl; + << ", error) {" << '\n'; + indent_up(); + from_string_mapping << indent() << "switch s {" << '\n'; + indent_down(); vector constants = tenum->get_constants(); vector::iterator c_iter; int value = -1; + indent_up(); for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) { value = (*c_iter)->get_value(); string iter_std_name(escape_string((*c_iter)->get_name())); string iter_name((*c_iter)->get_name()); - f_types_ << indent() << " " << tenum_name << "_" << iter_name << ' ' << tenum_name << " = " - << value << endl; + generate_deprecation_comment(f_types_, (*c_iter)->annotations_); + f_types_ << indent() << tenum_name << "_" << iter_name << ' ' << tenum_name << " = " + << value << '\n'; + known_values_mapping << indent() << tenum_name << "_" << iter_name << "," << '\n'; // Dictionaries to/from string names of enums - to_string_mapping << indent() << " case " << tenum_name << "_" << iter_name << ": return \"" - << iter_std_name << "\"" << endl; + to_string_mapping << indent() << "case " << tenum_name << "_" << iter_name << ": return \"" + << iter_std_name << "\"" << '\n'; if (iter_std_name != escape_string(iter_name)) { - from_string_mapping << indent() << " case \"" << iter_std_name << "\", \"" + from_string_mapping << indent() << "case \"" << iter_std_name << "\", \"" << escape_string(iter_name) << "\": return " << tenum_name << "_" - << iter_name << ", nil " << endl; + << iter_name << ", nil" << '\n'; } else { - from_string_mapping << indent() << " case \"" << iter_std_name << "\": return " << tenum_name - << "_" << iter_name << ", nil " << endl; + from_string_mapping << indent() << "case \"" << iter_std_name << "\": return " << tenum_name + << "_" << iter_name << ", nil" << '\n'; } } - to_string_mapping << indent() << " }" << endl; - to_string_mapping << indent() << " return \"\"" << endl; - to_string_mapping << indent() << "}" << endl; - from_string_mapping << indent() << " }" << endl; - from_string_mapping << indent() << " return " << tenum_name << "(0)," - << " fmt.Errorf(\"not a valid " << tenum_name << " string\")" << endl; - from_string_mapping << indent() << "}" << endl; + to_string_mapping << indent() << "}" << '\n'; + to_string_mapping << indent() << "return \"\"" << '\n'; + indent_down(); + to_string_mapping << indent() << "}" << '\n'; + indent_up(); + from_string_mapping << indent() << "}" << '\n'; + from_string_mapping << indent() << "return " << tenum_name << "(0)," + << " fmt.Errorf(\"not a valid " << tenum_name << " string\")" << '\n'; + indent_down(); + from_string_mapping << indent() << "}" << '\n'; + + known_values_mapping << indent() << "}" << '\n' << '\n'; + known_values_mapping << indent() << "func " << tenum_name << "Values() iter.Seq[" << tenum_name << "] {" << '\n'; + indent_up(); + known_values_mapping << indent() << "return func(yield func(" << tenum_name << ") bool) {" << '\n'; + indent_up(); + known_values_mapping << indent() << "for _, v := range known" << tenum_name << "Values {" << '\n'; + indent_up(); + known_values_mapping << indent() << "if !yield(v) {" << '\n'; + indent_up(); + known_values_mapping << indent() << "return" << '\n'; + indent_down(); + known_values_mapping << indent() << "}" << '\n'; + indent_down(); + known_values_mapping << indent() << "}" << '\n'; + indent_down(); + known_values_mapping << indent() << "}" << '\n'; + indent_down(); + known_values_mapping << indent() << "}" << '\n'; - f_types_ << ")" << endl << endl << to_string_mapping.str() << endl << from_string_mapping.str() - << endl << endl; + f_types_ << ")" << '\n' << '\n' + << known_values_mapping.str() << '\n' + << to_string_mapping.str() << '\n' + << from_string_mapping.str() << '\n' << '\n'; // Generate a convenience function that converts an instance of an enum // (which may be a constant) into a pointer to an instance of that enum // type. + generate_deprecation_comment(f_types_, tenum->annotations_); f_types_ << "func " << tenum_name << "Ptr(v " << tenum_name << ") *" << tenum_name - << " { return &v }" << endl << endl; + << " { return &v }" << '\n' << '\n'; // Generate MarshalText - f_types_ << "func (p " << tenum_name << ") MarshalText() ([]byte, error) {" << endl; - f_types_ << "return []byte(p.String()), nil" << endl; - f_types_ << "}" << endl << endl; + f_types_ << "func (p " << tenum_name << ") MarshalText() ([]byte, error) {" << '\n'; + indent_up(); + f_types_ << indent() << "return []byte(p.String()), nil" << '\n'; + indent_down(); + f_types_ << "}" << '\n' << '\n'; // Generate UnmarshalText - f_types_ << "func (p *" << tenum_name << ") UnmarshalText(text []byte) error {" << endl; - f_types_ << "q, err := " << tenum_name << "FromString(string(text))" << endl; - f_types_ << "if (err != nil) {" << endl << "return err" << endl << "}" << endl; - f_types_ << "*p = q" << endl; - f_types_ << "return nil" << endl; - f_types_ << "}" << endl << endl; + f_types_ << "func (p *" << tenum_name << ") UnmarshalText(text []byte) error {" << '\n'; + indent_up(); + f_types_ << indent() << "q, err := " << tenum_name << "FromString(string(text))" << '\n'; + f_types_ << indent() << "if err != nil {" << '\n'; + indent_up(); + f_types_ << indent() << "return err" << '\n'; + indent_down(); + f_types_ << indent() << "}" << '\n'; + f_types_ << indent() << "*p = q" << '\n'; + f_types_ << indent() << "return nil" << '\n'; + indent_down(); + f_types_ << "}" << '\n' << '\n'; // Generate Scan for sql.Scanner interface - f_types_ << "func (p *" << tenum_name << ") Scan(value interface{}) error {" <get_name()); t_const_value* value = tconst->get_value(); if (type->is_enum() || (type->is_base_type() && ((t_base_type*)type)->get_base() != t_base_type::TYPE_UUID)) { - indent(f_consts_) << "const " << name << " = " << render_const_value(type, value, name) << endl; + indent(f_consts_) << "const " << name << " = " << render_const_value(type, value, name) << '\n'; } else { - f_const_values_ << indent() << name << " = " << render_const_value(type, value, name) << endl - << endl; + f_const_values_ << indent() << name << " = " << render_const_value(type, value, name) << '\n' + << '\n'; - f_consts_ << indent() << "var " << name << " " << type_to_go_type(type) << endl; + f_consts_ << indent() << "var " << name << " " << type_to_go_type(type) << '\n'; } } @@ -1079,8 +1135,8 @@ string t_go_generator::render_const_value(t_type* type, t_const_value* value, co if (field_type == nullptr) { throw "type error: " + type->get_name() + " has no field " + v_iter->first->get_string(); } - out << endl << indent() << publicize(v_iter->first->get_string()) << ": " - << render_const_value(field_type, v_iter->second, name, is_optional) << "," << endl; + out << '\n' << indent() << publicize(v_iter->first->get_string()) << ": " + << render_const_value(field_type, v_iter->second, name, is_optional) << "," << '\n'; } indent_down(); @@ -1090,13 +1146,13 @@ string t_go_generator::render_const_value(t_type* type, t_const_value* value, co t_type* ktype = ((t_map*)type)->get_key_type(); t_type* vtype = ((t_map*)type)->get_val_type(); const map& val = value->get_map(); - out << "map[" << type_to_go_key_type(ktype) << "]" << type_to_go_type(vtype) << "{" << endl; + out << "map[" << type_to_go_key_type(ktype) << "]" << type_to_go_type(vtype) << "{" << '\n'; indent_up(); map::const_iterator v_iter; for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { out << indent() << render_const_value(ktype, v_iter->first, name) << ": " - << render_const_value(vtype, v_iter->second, name) << "," << endl; + << render_const_value(vtype, v_iter->second, name) << "," << '\n'; } indent_down(); @@ -1104,7 +1160,7 @@ string t_go_generator::render_const_value(t_type* type, t_const_value* value, co } else if (type->is_list()) { t_type* etype = ((t_list*)type)->get_elem_type(); const vector& val = value->get_list(); - out << "[]" << type_to_go_type(etype) << "{" << endl; + out << "[]" << type_to_go_type(etype) << "{" << '\n'; indent_up(); vector::const_iterator v_iter; @@ -1117,7 +1173,7 @@ string t_go_generator::render_const_value(t_type* type, t_const_value* value, co } else if (type->is_set()) { t_type* etype = ((t_set*)type)->get_elem_type(); const vector& val = value->get_list(); - out << "[]" << type_to_go_type(etype) << "{" << endl; + out << "[]" << type_to_go_type(etype) << "{" << '\n'; indent_up(); vector::const_iterator v_iter; @@ -1158,12 +1214,12 @@ void t_go_generator::generate_go_struct(t_struct* tstruct, bool is_exception) { generate_go_struct_definition(f_types_, tstruct, is_exception); // generate Validate function std::string tstruct_name(publicize(tstruct->get_name(), false)); - f_types_ << "func (p *" << tstruct_name << ") Validate() error {" << endl; + f_types_ << "func (p *" << tstruct_name << ") Validate() error {" << '\n'; indent_up(); go_validator_generator(this).generate_struct_validator(f_types_, tstruct); - f_types_ << indent() << "return nil" << endl; + f_types_ << indent() << "return nil" << '\n'; indent_down(); - f_types_ << "}" << endl; + f_types_ << "}" << '\n' << '\n'; } void t_go_generator::get_publicized_name_and_def_value(t_field* tfield, @@ -1179,20 +1235,26 @@ void t_go_generator::generate_go_struct_initializer(ostream& out, t_struct* tstruct, bool is_args_or_result) { out << publicize(type_name(tstruct), is_args_or_result) << "{"; + indent_up(); const vector& members = tstruct->get_members(); + bool empty = true; 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(member, &publicized_name, &def_value); if (!pointer_field && def_value != nullptr && !omit_initialization(member)) { - out << endl << indent() << publicized_name << ": " - << render_field_initial_value(member, member->get_name(), pointer_field) << "," - << endl; + empty = false; + out << '\n' << indent() << publicized_name << ": " + << render_field_initial_value(member, member->get_name(), pointer_field) << ","; } } - out << "}" << endl; + indent_down(); + if (!empty) { + out << '\n' << indent(); + } + out << "}" << '\n'; } /** @@ -1211,7 +1273,8 @@ void t_go_generator::generate_go_struct_definition(ostream& out, std::string tstruct_name(publicize(tstruct->get_name(), is_args || is_result)); generate_go_docstring(out, tstruct); - out << indent() << "type " << tstruct_name << " struct {" << endl; + generate_deprecation_comment(out, tstruct->annotations_); + out << indent() << "type " << tstruct_name << " struct {" << '\n'; /* Here we generate the structure specification for the fastbinary codec. These specifications have the following structure: @@ -1253,9 +1316,9 @@ void t_go_generator::generate_go_struct_definition(ostream& out, } int last_unused = sorted_keys_pos - 1; if (first_unused < last_unused) { - indent(out) << "// unused fields # " << first_unused << " to " << last_unused << endl; + indent(out) << "// unused fields # " << first_unused << " to " << last_unused << '\n'; } else if (first_unused == last_unused) { - indent(out) << "// unused field # " << first_unused << endl; + indent(out) << "// unused field # " << first_unused << '\n'; } } @@ -1290,31 +1353,34 @@ void t_go_generator::generate_go_struct_definition(ostream& out, // Trailing whitespace gotag.resize(gotag.size()-1); + generate_deprecation_comment(out, (*m_iter)->annotations_); indent(out) << publicize((*m_iter)->get_name()) << " " << goType << " `thrift:\"" << escape_string((*m_iter)->get_name()) << "," << sorted_keys_pos; if ((*m_iter)->get_req() == t_field::T_REQUIRED) { out << ",required"; } - out << "\" " << gotag << "`" << endl; + out << "\" " << gotag << "`" << '\n'; sorted_keys_pos++; } } else { for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { + generate_deprecation_comment(out, (*m_iter)->annotations_); // This fills in default values, as opposed to nulls out << indent() << publicize((*m_iter)->get_name()) << " " - << type_to_go_type((*m_iter)->get_type()) << endl; + << type_to_go_type((*m_iter)->get_type()) << '\n'; } } indent_down(); - out << indent() << "}" << endl << endl; - out << indent() << "func New" << tstruct_name << "() *" << tstruct_name << " {" << endl; + out << indent() << "}" << '\n' << '\n'; + generate_deprecation_comment(out, tstruct->annotations_); + out << indent() << "func New" << tstruct_name << "() *" << tstruct_name << " {" << '\n'; indent_up(); out << indent() << "return &"; generate_go_struct_initializer(out, tstruct, is_result || is_args); indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; // Default values for optional fields for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { string publicized_name; @@ -1324,12 +1390,14 @@ void t_go_generator::generate_go_struct_definition(ostream& out, string goType = type_to_go_type_with_opt(fieldType, false); string def_var_name = tstruct_name + "_" + publicized_name + "_DEFAULT"; if ((*m_iter)->get_req() == t_field::T_OPTIONAL || is_pointer_field(*m_iter)) { + generate_deprecation_comment(out, (*m_iter)->annotations_); out << indent() << "var " << def_var_name << " " << goType; if (def_value != nullptr) { out << " = " << render_const_value(fieldType, def_value, (*m_iter)->get_name()); } - out << endl; + out << '\n'; } + out << '\n'; // num_setable is used for deciding if Count* methods will be generated for union fields. // This applies to all nullable fields including slices (used for set, list and binary) and maps, not just pointers. @@ -1341,25 +1409,27 @@ void t_go_generator::generate_go_struct_definition(ostream& out, if (is_pointer_field(*m_iter)) { string goOptType = type_to_go_type_with_opt(fieldType, true); string maybepointer = goOptType != goType ? "*" : ""; + generate_deprecation_comment(out, (*m_iter)->annotations_); out << indent() << "func (p *" << tstruct_name << ") Get" << publicized_name << "() " - << goType << " {" << endl; + << goType << " {" << '\n'; indent_up(); - out << indent() << "if !p.IsSet" << publicized_name << "() {" << endl; + out << indent() << "if !p.IsSet" << publicized_name << "() {" << '\n'; indent_up(); - out << indent() << "return " << def_var_name << endl; + out << indent() << "return " << def_var_name << '\n'; indent_down(); - out << indent() << "}" << endl; - out << indent() << "return " << maybepointer << "p." << publicized_name << endl; + out << indent() << "}" << '\n'; + out << indent() << "return " << maybepointer << "p." << publicized_name << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n' << '\n'; } else { - out << endl; + out << '\n'; + generate_deprecation_comment(out, (*m_iter)->annotations_); out << indent() << "func (p *" << tstruct_name << ") Get" << publicized_name << "() " - << goType << " {" << endl; + << goType << " {" << '\n'; indent_up(); - out << indent() << "return p." << publicized_name << endl; + out << indent() << "return p." << publicized_name << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n' << '\n'; } } @@ -1374,57 +1444,57 @@ void t_go_generator::generate_go_struct_definition(ostream& out, generate_go_struct_equals(out, tstruct, tstruct_name); } - out << indent() << "func (p *" << tstruct_name << ") String() string {" << endl; + out << indent() << "func (p *" << tstruct_name << ") String() string {" << '\n'; indent_up(); - out << indent() << "if p == nil {" << endl; + out << indent() << "if p == nil {" << '\n'; indent_up(); - out << indent() << "return \"\"" << endl; + out << indent() << "return \"\"" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; out << indent() << "return fmt.Sprintf(\"" << escape_string(tstruct_name) << "(%+v)\", *p)" - << endl; + << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; if (is_exception) { - out << indent() << "func (p *" << tstruct_name << ") Error() string {" << endl; + out << indent() << "func (p *" << tstruct_name << ") Error() string {" << '\n'; indent_up(); - out << indent() << "return p.String()" << endl; + out << indent() << "return p.String()" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; - out << indent() << "func (" << tstruct_name << ") TExceptionType() thrift.TExceptionType {" << endl; + out << indent() << "func (" << tstruct_name << ") TExceptionType() thrift.TExceptionType {" << '\n'; indent_up(); - out << indent() << "return thrift.TExceptionTypeCompiled" << endl; + out << indent() << "return thrift.TExceptionTypeCompiled" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; out << indent() << "var _ thrift.TException = (*" << tstruct_name << ")(nil)" - << endl << endl; + << '\n' << '\n'; } if (!read_write_private_) { // Generate the implementation of slog.LogValuer, // see: https://issues.apache.org/jira/browse/THRIFT-5745 - out << indent() << "func (p *" << tstruct_name << ") LogValue() slog.Value {" << endl; + out << indent() << "func (p *" << tstruct_name << ") LogValue() slog.Value {" << '\n'; indent_up(); - out << indent() << "if p == nil {" << endl; + out << indent() << "if p == nil {" << '\n'; indent_up(); - out << indent() << "return slog.AnyValue(nil)" << endl; + out << indent() << "return slog.AnyValue(nil)" << '\n'; indent_down(); - out << indent() << "}" << endl; - out << indent() << "v := thrift.SlogTStructWrapper{" << endl; + out << indent() << "}" << '\n'; + out << indent() << "v := thrift.SlogTStructWrapper{" << '\n'; indent_up(); - out << indent() << "Type: \"*" << package_name_ << "." << tstruct_name << "\"," << endl; - out << indent() << "Value: p," << endl; + out << indent() << "Type: \"*" << package_name_ << "." << tstruct_name << "\"," << '\n'; + out << indent() << "Value: p," << '\n'; indent_down(); - out << indent() << "}" << endl; - out << indent() << "return slog.AnyValue(v)" << endl; + out << indent() << "}" << '\n'; + out << indent() << "return slog.AnyValue(v)" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; out << indent() << "var _ slog.LogValuer = (*" << tstruct_name << ")(nil)" - << endl << endl; + << '\n' << '\n'; } } @@ -1443,26 +1513,27 @@ void t_go_generator::generate_isset_helpers(ostream& out, for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { const string field_name(publicize(escape_string((*f_iter)->get_name()))); if ((*f_iter)->get_req() == t_field::T_OPTIONAL || is_pointer_field(*f_iter)) { + generate_deprecation_comment(out, (*f_iter)->annotations_); out << indent() << "func (p *" << tstruct_name << ") IsSet" << field_name << "() bool {" - << endl; + << '\n'; indent_up(); t_type* ttype = (*f_iter)->get_type()->get_true_type(); bool is_byteslice = ttype->is_binary(); bool compare_to_nil_only = ttype->is_set() || ttype->is_list() || ttype->is_map() || (is_byteslice && !(*f_iter)->get_value()); if (is_pointer_field(*f_iter) || compare_to_nil_only) { - out << indent() << "return p." << field_name << " != nil" << endl; + out << indent() << "return p." << field_name << " != nil" << '\n'; } else { string def_var_name = tstruct_name + "_" + field_name + "_DEFAULT"; if (is_byteslice) { out << indent() << "return !bytes.Equal(p." << field_name << ", " << def_var_name << ")" - << endl; + << '\n'; } else { - out << indent() << "return p." << field_name << " != " << def_var_name << endl; + out << indent() << "return p." << field_name << " != " << def_var_name << '\n'; } } indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } } } @@ -1480,9 +1551,9 @@ void t_go_generator::generate_countsetfields_helper(ostream& out, const string escaped_tstruct_name(escape_string(tstruct->get_name())); out << indent() << "func (p *" << tstruct_name << ") CountSetFields" << tstruct_name << "() int {" - << endl; + << '\n'; indent_up(); - out << indent() << "count := 0" << endl; + out << indent() << "count := 0" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if ((*f_iter)->get_req() == t_field::T_REQUIRED) continue; @@ -1494,16 +1565,16 @@ void t_go_generator::generate_countsetfields_helper(ostream& out, const string field_name(publicize(escape_string((*f_iter)->get_name()))); - out << indent() << "if (p.IsSet" << field_name << "()) {" << endl; + out << indent() << "if (p.IsSet" << field_name << "()) {" << '\n'; indent_up(); - out << indent() << "count++" << endl; + out << indent() << "count++" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } - out << indent() << "return count" << endl << endl; + out << indent() << "return count" << '\n' << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } /** @@ -1518,33 +1589,41 @@ void t_go_generator::generate_go_struct_reader(ostream& out, vector::const_iterator f_iter; string escaped_tstruct_name(escape_string(tstruct->get_name())); out << indent() << "func (p *" << tstruct_name << ") " << read_method_name_ << "(ctx context.Context, iprot thrift.TProtocol) error {" - << endl; + << '\n'; indent_up(); - out << indent() << "if _, err := iprot.ReadStructBegin(ctx); err != nil {" << endl; - out << indent() << " return thrift.PrependError(fmt.Sprintf(\"%T read error: \", p), err)" - << endl; - out << indent() << "}" << endl << endl; + out << indent() << "if _, err := iprot.ReadStructBegin(ctx); err != nil {" << '\n'; + indent_up(); + out << indent() << "return thrift.PrependError(fmt.Sprintf(\"%T read error: \", p), err)" + << '\n'; + indent_down(); + out << indent() << "}" << '\n' << '\n'; // Required variables does not have IsSet functions, so we need tmp vars to check them. for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if ((*f_iter)->get_req() == t_field::T_REQUIRED) { const string field_name(publicize(escape_string((*f_iter)->get_name()))); - indent(out) << "var isset" << field_name << " bool = false;" << endl; + indent(out) << "var isset" << field_name << " bool = false;" << '\n'; } } - out << endl; + out << '\n'; // Loop over reading in fields - indent(out) << "for {" << endl; + indent(out) << "for {" << '\n'; indent_up(); // Read beginning field marker - out << indent() << "_, fieldTypeId, fieldId, err := iprot.ReadFieldBegin(ctx)" << endl; - out << indent() << "if err != nil {" << endl; - out << indent() << " return thrift.PrependError(fmt.Sprintf(" - "\"%T field %d read error: \", p, fieldId), err)" << endl; - out << indent() << "}" << endl; + out << indent() << "_, fieldTypeId, fieldId, err := iprot.ReadFieldBegin(ctx)" << '\n'; + out << indent() << "if err != nil {" << '\n'; + indent_up(); + out << indent() << "return thrift.PrependError(fmt.Sprintf(" + "\"%T field %d read error: \", p, fieldId), err)" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; // Check for field STOP marker and break - out << indent() << "if fieldTypeId == thrift.STOP { break; }" << endl; + out << indent() << "if fieldTypeId == thrift.STOP {" << '\n'; + indent_up(); + out << indent() << "break" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; string thriftFieldTypeId; // Generate deserialization code for known cases @@ -1553,7 +1632,7 @@ void t_go_generator::generate_go_struct_reader(ostream& out, // Switch statement on the field we are reading, false if no fields present bool have_switch = !fields.empty(); if (have_switch) { - indent(out) << "switch fieldId {" << endl; + indent(out) << "switch fieldId {" << '\n'; } // All the fields we know @@ -1569,7 +1648,7 @@ void t_go_generator::generate_go_struct_reader(ostream& out, field_method_suffix *= -1; } - out << indent() << "case " << field_id << ":" << endl; + out << indent() << "case " << field_id << ":" << '\n'; indent_up(); thriftFieldTypeId = type_to_enum((*f_iter)->get_type()); @@ -1577,23 +1656,31 @@ void t_go_generator::generate_go_struct_reader(ostream& out, thriftFieldTypeId = "thrift.STRING"; } - out << indent() << "if fieldTypeId == " << thriftFieldTypeId << " {" << endl; - out << indent() << " if err := p." << field_method_prefix << field_method_suffix << "(ctx, iprot); err != nil {" - << endl; - out << indent() << " return err" << endl; - out << indent() << " }" << endl; + out << indent() << "if fieldTypeId == " << thriftFieldTypeId << " {" << '\n'; + indent_up(); + out << indent() << "if err := p." << field_method_prefix << field_method_suffix << "(ctx, iprot); err != nil {" + << '\n'; + indent_up(); + out << indent() << "return err" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; // Mark required field as read if ((*f_iter)->get_req() == t_field::T_REQUIRED) { const string field_name(publicize(escape_string((*f_iter)->get_name()))); - out << indent() << " isset" << field_name << " = true" << endl; + out << indent() << "isset" << field_name << " = true" << '\n'; } - out << indent() << "} else {" << endl; - out << indent() << " if err := iprot.Skip(ctx, fieldTypeId); err != nil {" << endl; - out << indent() << " return err" << endl; - out << indent() << " }" << endl; - out << indent() << "}" << endl; + indent_down(); + out << indent() << "} else {" << '\n'; + indent_up(); + out << indent() << "if err := iprot.Skip(ctx, fieldTypeId); err != nil {" << '\n'; + indent_up(); + out << indent() << "return err" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; indent_down(); @@ -1601,46 +1688,54 @@ void t_go_generator::generate_go_struct_reader(ostream& out, // Begin switch default case if (have_switch) { - out << indent() << "default:" << endl; + out << indent() << "default:" << '\n'; indent_up(); } // Skip unknown fields in either case - out << indent() << "if err := iprot.Skip(ctx, fieldTypeId); err != nil {" << endl; - out << indent() << " return err" << endl; - out << indent() << "}" << endl; + out << indent() << "if err := iprot.Skip(ctx, fieldTypeId); err != nil {" << '\n'; + indent_up(); + out << indent() << "return err" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; // End switch default case if (have_switch) { indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } // Read field end marker - out << indent() << "if err := iprot.ReadFieldEnd(ctx); err != nil {" << endl; - out << indent() << " return err" << endl; - out << indent() << "}" << endl; + out << indent() << "if err := iprot.ReadFieldEnd(ctx); err != nil {" << '\n'; + indent_up(); + out << indent() << "return err" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; indent_down(); - out << indent() << "}" << endl; - out << indent() << "if err := iprot.ReadStructEnd(ctx); err != nil {" << endl; - out << indent() << " return thrift.PrependError(fmt.Sprintf(" - "\"%T read struct end error: \", p), err)" << endl; - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; + out << indent() << "if err := iprot.ReadStructEnd(ctx); err != nil {" << '\n'; + indent_up(); + out << indent() << "return thrift.PrependError(fmt.Sprintf(" + "\"%T read struct end error: \", p), err)" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; // Return error if any required fields are missing. for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if ((*f_iter)->get_req() == t_field::T_REQUIRED) { const string field_name(publicize(escape_string((*f_iter)->get_name()))); - out << indent() << "if !isset" << field_name << "{" << endl; - out << indent() << " return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, " - "fmt.Errorf(\"Required field " << field_name << " is not set\"));" << endl; - out << indent() << "}" << endl; + out << indent() << "if !isset" << field_name << "{" << '\n'; + indent_up(); + out << indent() << "return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, " + << "fmt.Errorf(\"Required field " << field_name << " is not set\"))" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; } } - out << indent() << "return nil" << endl; + out << indent() << "return nil" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { string field_type_name(publicize((*f_iter)->get_type()->get_name())); @@ -1654,13 +1749,13 @@ void t_go_generator::generate_go_struct_reader(ostream& out, field_method_suffix *= -1; } - out << indent() << "func (p *" << tstruct_name << ") " << field_method_prefix << field_method_suffix - << "(ctx context.Context, iprot thrift.TProtocol) error {" << endl; + out << indent() << "func (p *" << tstruct_name << ") " << field_method_prefix << field_method_suffix + << "(ctx context.Context, iprot thrift.TProtocol) error {" << '\n'; indent_up(); generate_deserialize_field(out, *f_iter, false, "p."); + out << indent() << "return nil" << '\n'; indent_down(); - out << indent() << " return nil" << endl; - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } } @@ -1673,18 +1768,23 @@ void t_go_generator::generate_go_struct_writer(ostream& out, string name(tstruct->get_name()); const vector& fields = tstruct->get_sorted_members(); vector::const_iterator f_iter; - indent(out) << "func (p *" << tstruct_name << ") " << write_method_name_ << "(ctx context.Context, oprot thrift.TProtocol) error {" << endl; + indent(out) << "func (p *" << tstruct_name << ") " << write_method_name_ << "(ctx context.Context, oprot thrift.TProtocol) error {" << '\n'; indent_up(); if (tstruct->is_union() && uses_countsetfields) { std::string tstruct_name(publicize(tstruct->get_name())); - out << indent() << "if c := p.CountSetFields" << tstruct_name << "(); c != 1 {" << endl - << indent() - << " return fmt.Errorf(\"%T write union: exactly one field must be set (%d set)\", p, c)" - << endl << indent() << "}" << endl; + out << indent() << "if c := p.CountSetFields" << tstruct_name << "(); c != 1 {" << '\n'; + indent_up(); + out << indent() << "return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, " + << "fmt.Errorf(\"%T write union: exactly one field must be set (%d set)\", p, c))" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; } - out << indent() << "if err := oprot.WriteStructBegin(ctx, \"" << name << "\"); err != nil {" << endl; - out << indent() << " return thrift.PrependError(fmt.Sprintf(" - "\"%T write struct begin error: \", p), err) }" << endl; + out << indent() << "if err := oprot.WriteStructBegin(ctx, \"" << name << "\"); err != nil {" << '\n'; + indent_up(); + out << indent() << "return thrift.PrependError(fmt.Sprintf(" + "\"%T write struct begin error: \", p), err)" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; string field_name; string escape_field_name; @@ -1692,7 +1792,7 @@ void t_go_generator::generate_go_struct_writer(ostream& out, t_field::e_req field_required; int32_t field_id = -1; - out << indent() << "if p != nil {" << endl; + out << indent() << "if p != nil {" << '\n'; indent_up(); for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { @@ -1708,20 +1808,26 @@ void t_go_generator::generate_go_struct_writer(ostream& out, } out << indent() << "if err := p." << field_method_prefix << field_method_suffix - << "(ctx, oprot); err != nil { return err }" << endl; + << "(ctx, oprot); err != nil { return err }" << '\n'; } indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; // Write the struct map - out << indent() << "if err := oprot.WriteFieldStop(ctx); err != nil {" << endl; - out << indent() << " return thrift.PrependError(\"write field stop error: \", err) }" << endl; - out << indent() << "if err := oprot.WriteStructEnd(ctx); err != nil {" << endl; - out << indent() << " return thrift.PrependError(\"write struct stop error: \", err) }" << endl; - out << indent() << "return nil" << endl; + out << indent() << "if err := oprot.WriteFieldStop(ctx); err != nil {" << '\n'; + indent_up(); + out << indent() << "return thrift.PrependError(\"write field stop error: \", err)" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n'; + out << indent() << "if err := oprot.WriteStructEnd(ctx); err != nil {" << '\n'; + indent_up(); + out << indent() << "return thrift.PrependError(\"write struct stop error: \", err)" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; + out << indent() << "return nil" << '\n'; + indent_down(); + out << indent() << "}" << '\n' << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { string field_method_prefix("writeField"); @@ -1738,35 +1844,41 @@ void t_go_generator::generate_go_struct_writer(ostream& out, } out << indent() << "func (p *" << tstruct_name << ") " << field_method_prefix << field_method_suffix - << "(ctx context.Context, oprot thrift.TProtocol) (err error) {" << endl; + << "(ctx context.Context, oprot thrift.TProtocol) (err error) {" << '\n'; indent_up(); if (field_required == t_field::T_OPTIONAL) { - out << indent() << "if p.IsSet" << publicize(field_name) << "() {" << endl; + out << indent() << "if p.IsSet" << publicize(field_name) << "() {" << '\n'; indent_up(); } out << indent() << "if err := oprot.WriteFieldBegin(ctx, \"" << escape_field_name << "\", " - << type_to_enum((*f_iter)->get_type()) << ", " << field_id << "); err != nil {" << endl; - out << indent() << " return thrift.PrependError(fmt.Sprintf(\"%T write field begin error " - << field_id << ":" << escape_field_name << ": \", p), err) }" << endl; + << type_to_enum((*f_iter)->get_type()) << ", " << field_id << "); err != nil {" << '\n'; + indent_up(); + out << indent() << "return thrift.PrependError(fmt.Sprintf(\"%T write field begin error " + << field_id << ":" << escape_field_name << ": \", p), err)" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; // Write field contents generate_serialize_field(out, *f_iter, "p."); // Write field closer - out << indent() << "if err := oprot.WriteFieldEnd(ctx); err != nil {" << endl; - out << indent() << " return thrift.PrependError(fmt.Sprintf(\"%T write field end error " - << field_id << ":" << escape_field_name << ": \", p), err) }" << endl; + out << indent() << "if err := oprot.WriteFieldEnd(ctx); err != nil {" << '\n'; + indent_up(); + out << indent() << "return thrift.PrependError(fmt.Sprintf(\"%T write field end error " + << field_id << ":" << escape_field_name << ": \", p), err)" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; if (field_required == t_field::T_OPTIONAL) { indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } + out << indent() << "return err" << '\n'; indent_down(); - out << indent() << " return err" << endl; - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } } @@ -1777,20 +1889,20 @@ void t_go_generator::generate_go_struct_equals(ostream& out, const vector& fields = tstruct->get_sorted_members(); vector::const_iterator f_iter; indent(out) << "func (p *" << tstruct_name << ") " << equals_method_name_ << "(other *" - << tstruct_name << ") bool {" << endl; + << tstruct_name << ") bool {" << '\n'; indent_up(); string field_name; string publicize_field_name; - out << indent() << "if p == other {" << endl; + out << indent() << "if p == other {" << '\n'; indent_up(); - out << indent() << "return true" << endl; + out << indent() << "return true" << '\n'; indent_down(); - out << indent() << "} else if p == nil || other == nil {" << endl; + out << indent() << "} else if p == nil || other == nil {" << '\n'; indent_up(); - out << indent() << "return false" << endl; + out << indent() << "return false" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { field_name = (*f_iter)->get_name(); @@ -1806,23 +1918,23 @@ void t_go_generator::generate_go_struct_equals(ostream& out, && (ttype->is_base_type() || ttype->is_enum() || ttype->is_container())) { string tgtv = "(*" + tgt + ")"; string srcv = "(*" + src + ")"; - out << indent() << "if " << tgt << " != " << src << " {" << endl; + out << indent() << "if " << tgt << " != " << src << " {" << '\n'; indent_up(); - out << indent() << "if " << tgt << " == nil || " << src << " == nil {" << endl; + out << indent() << "if " << tgt << " == nil || " << src << " == nil {" << '\n'; indent_up(); - out << indent() << "return false" << endl; + out << indent() << "return false" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; generate_go_equals(out, field_type, tgtv, srcv); indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } else { generate_go_equals(out, field_type, tgt, src); } } - out << indent() << "return true" << endl; + out << indent() << "return true" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } /** @@ -1842,7 +1954,7 @@ void t_go_generator::generate_service(t_service* tservice) { if(!skip_remote_) { generate_service_remote(tservice); } - f_types_ << endl; + f_types_ << '\n'; } /** @@ -1853,7 +1965,7 @@ void t_go_generator::generate_service(t_service* tservice) { void t_go_generator::generate_service_helpers(t_service* tservice) { vector functions = tservice->get_functions(); vector::iterator f_iter; - f_types_ << "// HELPER FUNCTIONS AND STRUCTURES" << endl << endl; + f_types_ << "// HELPER FUNCTIONS AND STRUCTURES" << '\n' << '\n'; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { t_struct* ts = (*f_iter)->get_arglist(); @@ -1906,31 +2018,35 @@ void t_go_generator::generate_service_interface(t_service* tservice) { extends = type_name(tservice->get_extends()); size_t index = extends.rfind("."); + indent_up(); if (index != string::npos) { - extends_if = "\n" + indent() + " " + extends.substr(0, index + 1) + extends_if = "\n" + indent() + extends.substr(0, index + 1) + publicize(extends.substr(index + 1)) + "\n"; } else { extends_if = "\n" + indent() + publicize(extends) + "\n"; } + indent_down(); } + generate_deprecation_comment(f_types_, tservice->annotations_); f_types_ << indent() << "type " << interfaceName << " interface {" << extends_if; indent_up(); generate_go_docstring(f_types_, tservice); vector functions = tservice->get_functions(); if (!functions.empty()) { - f_types_ << endl; + f_types_ << '\n'; vector::iterator f_iter; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { generate_go_docstring(f_types_, (*f_iter)); - f_types_ << indent() << function_signature_if(*f_iter, "", true) << endl; + generate_deprecation_comment(f_types_, (*f_iter)->annotations_); + f_types_ << indent() << function_signature_if(*f_iter, "", true) << '\n'; } } indent_down(); - f_types_ << indent() << "}" << endl << endl; + f_types_ << indent() << "}" << '\n' << '\n'; } /** @@ -1963,23 +2079,25 @@ void t_go_generator::generate_service_client(t_service* tservice) { extends_field = extends_client.substr(extends_client.find(".") + 1); generate_go_docstring(f_types_, tservice); - f_types_ << indent() << "type " << serviceName << "Client struct {" << endl; + generate_deprecation_comment(f_types_, tservice->annotations_); + f_types_ << indent() << "type " << serviceName << "Client struct {" << '\n'; indent_up(); if (!extends_client.empty()) { - f_types_ << indent() << "*" << extends_client << endl; + f_types_ << indent() << "*" << extends_client << '\n'; } else { - f_types_ << indent() << "c thrift.TClient" << endl; - f_types_ << indent() << "meta thrift.ResponseMeta" << endl; + f_types_ << indent() << "c thrift.TClient" << '\n'; + f_types_ << indent() << "meta thrift.ResponseMeta" << '\n'; } indent_down(); - f_types_ << indent() << "}" << endl << endl; + f_types_ << indent() << "}" << '\n' << '\n'; // Legacy constructor function + generate_deprecation_comment(f_types_, tservice->annotations_); f_types_ << indent() << "func New" << serviceName << "ClientFactory(t thrift.TTransport, f thrift.TProtocolFactory) *" << serviceName - << "Client {" << endl; + << "Client {" << '\n'; indent_up(); f_types_ << indent() << "return &" << serviceName << "Client"; @@ -1987,72 +2105,74 @@ void t_go_generator::generate_service_client(t_service* tservice) { f_types_ << "{" << extends_field << ": " << extends_client_new << "Factory(t, f)}"; } else { indent_up(); - f_types_ << "{" << endl; - f_types_ << indent() << "c: thrift.NewTStandardClient(f.GetProtocol(t), f.GetProtocol(t))," << endl; + f_types_ << "{" << '\n'; + f_types_ << indent() << "c: thrift.NewTStandardClient(f.GetProtocol(t), f.GetProtocol(t))," << '\n'; indent_down(); - f_types_ << indent() << "}" << endl; + f_types_ << indent() << "}" << '\n'; } indent_down(); - f_types_ << indent() << "}" << endl << endl; + f_types_ << indent() << "}" << '\n' << '\n'; // Legacy constructor function with custom input & output protocols + generate_deprecation_comment(f_types_, tservice->annotations_); f_types_ << indent() << "func New" << serviceName << "ClientProtocol(t thrift.TTransport, iprot thrift.TProtocol, oprot thrift.TProtocol) *" - << serviceName << "Client {" << endl; + << serviceName << "Client {" << '\n'; indent_up(); f_types_ << indent() << "return &" << serviceName << "Client"; if (!extends.empty()) { f_types_ << "{" << extends_field << ": " << extends_client_new << "Protocol(t, iprot, oprot)}" - << endl; + << '\n'; } else { indent_up(); - f_types_ << "{" << endl; - f_types_ << indent() << "c: thrift.NewTStandardClient(iprot, oprot)," << endl; + f_types_ << "{" << '\n'; + f_types_ << indent() << "c: thrift.NewTStandardClient(iprot, oprot)," << '\n'; indent_down(); - f_types_ << indent() << "}" << endl; + f_types_ << indent() << "}" << '\n'; } indent_down(); - f_types_ << indent() << "}" << endl << endl; + f_types_ << indent() << "}" << '\n' << '\n'; // Constructor function + generate_deprecation_comment(f_types_, tservice->annotations_); f_types_ << indent() << "func New" << serviceName - << "Client(c thrift.TClient) *" << serviceName << "Client {" << endl; + << "Client(c thrift.TClient) *" << serviceName << "Client {" << '\n'; indent_up(); - f_types_ << indent() << "return &" << serviceName << "Client{" << endl; + f_types_ << indent() << "return &" << serviceName << "Client{" << '\n'; indent_up(); if (!extends.empty()) { - f_types_ << indent() << extends_field << ": " << extends_client_new << "(c)," << endl; + f_types_ << indent() << extends_field << ": " << extends_client_new << "(c)," << '\n'; } else { - f_types_ << indent() << "c: c," << endl; + f_types_ << indent() << "c: c," << '\n'; } indent_down(); - f_types_ << indent() << "}" << endl; + f_types_ << indent() << "}" << '\n'; indent_down(); - f_types_ << indent() << "}" << endl << endl; + f_types_ << indent() << "}" << '\n' << '\n'; if (extends.empty()) { - f_types_ << indent() << "func (p *" << serviceName << "Client) Client_() thrift.TClient {" << endl; + f_types_ << indent() << "func (p *" << serviceName << "Client) Client_() thrift.TClient {" << '\n'; indent_up(); - f_types_ << indent() << "return p.c" << endl; + f_types_ << indent() << "return p.c" << '\n'; indent_down(); - f_types_ << indent() << "}" << endl << endl; + f_types_ << indent() << "}" << '\n' << '\n'; - f_types_ << indent() << "func (p *" << serviceName << "Client) LastResponseMeta_() thrift.ResponseMeta {" << endl; + f_types_ << indent() << "func (p *" << serviceName << "Client) LastResponseMeta_() thrift.ResponseMeta {" << '\n'; indent_up(); - f_types_ << indent() << "return p.meta" << endl; + f_types_ << indent() << "return p.meta" << '\n'; indent_down(); - f_types_ << indent() << "}" << endl << endl; + f_types_ << indent() << "}" << '\n' << '\n'; - f_types_ << indent() << "func (p *" << serviceName << "Client) SetLastResponseMeta_(meta thrift.ResponseMeta) {" << endl; + f_types_ << indent() << "func (p *" << serviceName << "Client) SetLastResponseMeta_(meta thrift.ResponseMeta) {" << '\n'; indent_up(); - f_types_ << indent() << "p.meta = meta" << endl; + f_types_ << indent() << "p.meta = meta" << '\n'; indent_down(); - f_types_ << indent() << "}" << endl << endl; + f_types_ << indent() << "}" << '\n' << '\n'; } // Generate client method implementations @@ -2066,60 +2186,61 @@ void t_go_generator::generate_service_client(t_service* tservice) { string funname = publicize((*f_iter)->get_name()); // Open function generate_go_docstring(f_types_, (*f_iter)); + generate_deprecation_comment(f_types_, (*f_iter)->annotations_); f_types_ << indent() << "func (p *" << serviceName << "Client) " - << function_signature_if(*f_iter, "", true) << " {" << endl; + << function_signature_if(*f_iter, "", true) << " {" << '\n'; indent_up(); std::string method = (*f_iter)->get_name(); std::string argsType = publicize(method + "_args", true); std::string argsName = tmp("_args"); - f_types_ << indent() << "var " << argsName << " " << argsType << endl; + f_types_ << indent() << "var " << argsName << " " << argsType << '\n'; for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) { f_types_ << indent() << argsName << "." << publicize((*fld_iter)->get_name()) - << " = " << variable_name_to_go_name((*fld_iter)->get_name()) << endl; + << " = " << variable_name_to_go_name((*fld_iter)->get_name()) << '\n'; } if (!(*f_iter)->is_oneway()) { std::string metaName = tmp("_meta"); std::string resultName = tmp("_result"); std::string resultType = publicize(method + "_result", true); - f_types_ << indent() << "var " << resultName << " " << resultType << endl; - f_types_ << indent() << "var " << metaName << " thrift.ResponseMeta" << endl; + f_types_ << indent() << "var " << resultName << " " << resultType << '\n'; + f_types_ << indent() << "var " << metaName << " thrift.ResponseMeta" << '\n'; f_types_ << indent() << metaName << ", _err = p.Client_().Call(ctx, \"" - << method << "\", &" << argsName << ", &" << resultName << ")" << endl; - f_types_ << indent() << "p.SetLastResponseMeta_(" << metaName << ")" << endl; - f_types_ << indent() << "if _err != nil {" << endl; + << method << "\", &" << argsName << ", &" << resultName << ")" << '\n'; + f_types_ << indent() << "p.SetLastResponseMeta_(" << metaName << ")" << '\n'; + f_types_ << indent() << "if _err != nil {" << '\n'; indent_up(); - f_types_ << indent() << "return" << endl; + f_types_ << indent() << "return" << '\n'; indent_down(); - f_types_ << indent() << "}" << endl; + f_types_ << indent() << "}" << '\n'; t_struct* xs = (*f_iter)->get_xceptions(); const std::vector& xceptions = xs->get_members(); vector::const_iterator x_iter; if (!xceptions.empty()) { - f_types_ << indent() << "switch {" << endl; + f_types_ << indent() << "switch {" << '\n'; for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { const std::string pubname = publicize((*x_iter)->get_name()); const std::string field = resultName + "." + pubname; - f_types_ << indent() << "case " << field << "!= nil:" << endl; + f_types_ << indent() << "case " << field << "!= nil:" << '\n'; indent_up(); if (!(*f_iter)->get_returntype()->is_void()) { - f_types_ << indent() << "return _r, " << field << endl; + f_types_ << indent() << "return _r, " << field << '\n'; } else { - f_types_ << indent() << "return "<< field << endl; + f_types_ << indent() << "return "<< field << '\n'; } indent_down(); } - f_types_ << indent() << "}" << endl << endl; + f_types_ << indent() << "}" << '\n' << '\n'; } if ((*f_iter)->get_returntype()->is_struct()) { @@ -2130,37 +2251,37 @@ void t_go_generator::generate_service_client(t_service* tservice) { // struct in go. std::string retName = tmp("_ret"); f_types_ << indent() << "if " << retName << " := " << resultName - << ".GetSuccess(); " << retName << " != nil {" << endl; + << ".GetSuccess(); " << retName << " != nil {" << '\n'; indent_up(); - f_types_ << indent() << "return " << retName << ", nil" << endl; + f_types_ << indent() << "return " << retName << ", nil" << '\n'; indent_down(); - f_types_ << indent() << "}" << endl; + f_types_ << indent() << "}" << '\n'; f_types_ << indent() << "return nil, " << "thrift.NewTApplicationException(thrift.MISSING_RESULT, \"" - << method << " failed: unknown result\")" << endl; + << method << " failed: unknown result\")" << '\n'; } else if (!(*f_iter)->get_returntype()->is_void()) { - f_types_ << indent() << "return " << resultName << ".GetSuccess(), nil" << endl; + f_types_ << indent() << "return " << resultName << ".GetSuccess(), nil" << '\n'; } else { - f_types_ << indent() << "return nil" << endl; + f_types_ << indent() << "return nil" << '\n'; } } else { // Since we don't have response meta for oneway calls, overwrite it with // an empty one to avoid users getting the meta from last call and // mistaken it as from the oneway call. - f_types_ << indent() << "p.SetLastResponseMeta_(thrift.ResponseMeta{})" << endl; + f_types_ << indent() << "p.SetLastResponseMeta_(thrift.ResponseMeta{})" << '\n'; // TODO: would be nice to not to duplicate the call generation f_types_ << indent() << "if _, err := p.Client_().Call(ctx, \"" - << method << "\", &" << argsName << ", nil); err != nil {" << endl; + << method << "\", &" << argsName << ", nil); err != nil {" << '\n'; indent_up(); - f_types_ << indent() << "return err" << endl; + f_types_ << indent() << "return err" << '\n'; indent_down(); - f_types_ << indent() << "}" << endl; - f_types_ << indent() << "return nil" << endl; + f_types_ << indent() << "}" << '\n'; + f_types_ << indent() << "return nil" << '\n'; } indent_down(); - f_types_ << "}" << endl << endl; + f_types_ << "}" << '\n' << '\n'; } } @@ -2223,26 +2344,27 @@ void t_go_generator::generate_service_remote(t_service* tservice) { system_packages.push_back("thrift \"" + gen_thrift_import_ + "\""); f_remote << go_autogen_comment(); - f_remote << indent() << "package main" << endl << endl; - f_remote << indent() << "import (" << endl; + f_remote << indent() << "package main" << '\n' << '\n'; + f_remote << indent() << "import (" << '\n'; f_remote << render_system_packages(system_packages); f_remote << indent() << render_included_programs(unused_protection); f_remote << render_program_import(program_, unused_protection); - f_remote << indent() << ")" << endl; - f_remote << indent() << endl; + f_remote << indent() << ")" << '\n'; + f_remote << indent() << '\n'; f_remote << indent() << unused_protection; // filled in render_included_programs() - f_remote << indent() << endl; - f_remote << indent() << "func Usage() {" << endl; - f_remote << indent() << " fmt.Fprintln(os.Stderr, \"Usage of \", os.Args[0], \" " + f_remote << indent() << '\n'; + f_remote << indent() << "func Usage() {" << '\n'; + indent_up(); + f_remote << indent() << "fmt.Fprintln(os.Stderr, \"Usage of \", os.Args[0], \" " "[-h host:port] [-u url] [-f[ramed]] function [arg1 [arg2...]]:\")" - << endl; - f_remote << indent() << " flag.PrintDefaults()" << endl; - f_remote << indent() << " fmt.Fprintln(os.Stderr, \"\\nFunctions:\")" << endl; + << '\n'; + f_remote << indent() << "flag.PrintDefaults()" << '\n'; + f_remote << indent() << "fmt.Fprintln(os.Stderr, \"\\nFunctions:\")" << '\n'; string package_name_aliased = package_identifiers_[get_real_go_module(program_)]; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { - f_remote << " fmt.Fprintln(os.Stderr, \" " << (*f_iter)->get_returntype()->get_name() << " " + f_remote << indent() << "fmt.Fprintln(os.Stderr, \" " << (*f_iter)->get_returntype()->get_name() << " " << (*f_iter)->get_name() << "("; t_struct* arg_struct = (*f_iter)->get_arglist(); const std::vector& args = arg_struct->get_members(); @@ -2259,143 +2381,184 @@ void t_go_generator::generate_service_remote(t_service* tservice) { f_remote << args[i]->get_type()->get_name() << " " << args[i]->get_name(); } - f_remote << ")\")" << endl; + f_remote << ")\")" << '\n'; } - f_remote << indent() << " fmt.Fprintln(os.Stderr)" << endl; - f_remote << indent() << " os.Exit(0)" << endl; - f_remote << indent() << "}" << endl; - f_remote << indent() << endl; - - f_remote << indent() << "type httpHeaders map[string]string" << endl; - f_remote << indent() << endl; - f_remote << indent() << "func (h httpHeaders) String() string {" << endl; - f_remote << indent() << " var m map[string]string = h" << endl; - f_remote << indent() << " return fmt.Sprintf(\"%s\", m)" << endl; - f_remote << indent() << "}" << endl; - f_remote << indent() << endl; - f_remote << indent() << "func (h httpHeaders) Set(value string) error {" << endl; - f_remote << indent() << " parts := strings.Split(value, \": \")" << endl; - f_remote << indent() << " if len(parts) != 2 {" << endl; - f_remote << indent() << " return fmt.Errorf(\"header should be of format 'Key: Value'\")" << endl; - f_remote << indent() << " }" << endl; - f_remote << indent() << " h[parts[0]] = parts[1]" << endl; - f_remote << indent() << " return nil" << endl; - f_remote << indent() << "}" << endl; - f_remote << indent() << endl; - - f_remote << indent() << "func main() {" << endl; + f_remote << indent() << "fmt.Fprintln(os.Stderr)" << '\n'; + f_remote << indent() << "os.Exit(0)" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; + f_remote << indent() << '\n'; + + f_remote << indent() << "type httpHeaders map[string]string" << '\n'; + f_remote << indent() << '\n'; + f_remote << indent() << "func (h httpHeaders) String() string {" << '\n'; + indent_up(); + f_remote << indent() << "var m map[string]string = h" << '\n'; + f_remote << indent() << "return fmt.Sprintf(\"%s\", m)" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; + f_remote << indent() << '\n'; + f_remote << indent() << "func (h httpHeaders) Set(value string) error {" << '\n'; + indent_up(); + f_remote << indent() << "parts := strings.Split(value, \": \")" << '\n'; + f_remote << indent() << "if len(parts) != 2 {" << '\n'; + indent_up(); + f_remote << indent() << "return fmt.Errorf(\"header should be of format 'Key: Value'\")" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; + f_remote << indent() << "h[parts[0]] = parts[1]" << '\n'; + f_remote << indent() << "return nil" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; + f_remote << indent() << '\n'; + + f_remote << indent() << "func main() {" << '\n'; indent_up(); - f_remote << indent() << "flag.Usage = Usage" << endl; - f_remote << indent() << "var host string" << endl; - f_remote << indent() << "var port int" << endl; - f_remote << indent() << "var protocol string" << endl; - f_remote << indent() << "var urlString string" << endl; - f_remote << indent() << "var framed bool" << endl; - f_remote << indent() << "var useHttp bool" << endl; - f_remote << indent() << "headers := make(httpHeaders)" << endl; - f_remote << indent() << "var parsedUrl *url.URL" << endl; - f_remote << indent() << "var trans thrift.TTransport" << endl; - f_remote << indent() << "_ = strconv.Atoi" << endl; - f_remote << indent() << "_ = math.Abs" << endl; - f_remote << indent() << "flag.Usage = Usage" << endl; + f_remote << indent() << "flag.Usage = Usage" << '\n'; + f_remote << indent() << "var host string" << '\n'; + f_remote << indent() << "var port int" << '\n'; + f_remote << indent() << "var protocol string" << '\n'; + f_remote << indent() << "var urlString string" << '\n'; + f_remote << indent() << "var framed bool" << '\n'; + f_remote << indent() << "var useHttp bool" << '\n'; + f_remote << indent() << "headers := make(httpHeaders)" << '\n'; + f_remote << indent() << "var parsedUrl *url.URL" << '\n'; + f_remote << indent() << "var trans thrift.TTransport" << '\n'; + f_remote << indent() << "_ = strconv.Atoi" << '\n'; + f_remote << indent() << "_ = math.Abs" << '\n'; + f_remote << indent() << "flag.Usage = Usage" << '\n'; f_remote << indent() << "flag.StringVar(&host, \"h\", \"localhost\", \"Specify host and port\")" - << endl; - f_remote << indent() << "flag.IntVar(&port, \"p\", 9090, \"Specify port\")" << endl; + << '\n'; + f_remote << indent() << "flag.IntVar(&port, \"p\", 9090, \"Specify port\")" << '\n'; f_remote << indent() << "flag.StringVar(&protocol, \"P\", \"binary\", \"" - "Specify the protocol (binary, compact, simplejson, json)\")" << endl; - f_remote << indent() << "flag.StringVar(&urlString, \"u\", \"\", \"Specify the url\")" << endl; + "Specify the protocol (binary, compact, simplejson, json)\")" << '\n'; + f_remote << indent() << "flag.StringVar(&urlString, \"u\", \"\", \"Specify the url\")" << '\n'; f_remote << indent() << "flag.BoolVar(&framed, \"framed\", false, \"Use framed transport\")" - << endl; - f_remote << indent() << "flag.BoolVar(&useHttp, \"http\", false, \"Use http\")" << endl; - f_remote << indent() << "flag.Var(headers, \"H\", \"Headers to set on the http(s) request (e.g. -H \\\"Key: Value\\\")\")" << endl; - f_remote << indent() << "flag.Parse()" << endl; - f_remote << indent() << endl; - f_remote << indent() << "if len(urlString) > 0 {" << endl; - f_remote << indent() << " var err error" << endl; - f_remote << indent() << " parsedUrl, err = url.Parse(urlString)" << endl; - f_remote << indent() << " if err != nil {" << endl; - f_remote << indent() << " fmt.Fprintln(os.Stderr, \"Error parsing URL: \", err)" << endl; - f_remote << indent() << " flag.Usage()" << endl; - f_remote << indent() << " }" << endl; - f_remote << indent() << " host = parsedUrl.Host" << endl; - f_remote << indent() << " useHttp = len(parsedUrl.Scheme) <= 0 || parsedUrl.Scheme == \"http\" || parsedUrl.Scheme == \"https\"" - << endl; - f_remote << indent() << "} else if useHttp {" << endl; - f_remote << indent() << " _, err := url.Parse(fmt.Sprint(\"http://\", host, \":\", port))" - << endl; - f_remote << indent() << " if err != nil {" << endl; - f_remote << indent() << " fmt.Fprintln(os.Stderr, \"Error parsing URL: \", err)" << endl; - f_remote << indent() << " flag.Usage()" << endl; - f_remote << indent() << " }" << endl; - f_remote << indent() << "}" << endl; - f_remote << indent() << endl; - f_remote << indent() << "cmd := flag.Arg(0)" << endl; - f_remote << indent() << "var err error" << endl; - f_remote << indent() << "var cfg *thrift.TConfiguration = nil" << endl; - f_remote << indent() << "if useHttp {" << endl; - f_remote << indent() << " trans, err = thrift.NewTHttpClient(parsedUrl.String())" << endl; - f_remote << indent() << " if len(headers) > 0 {" << endl; - f_remote << indent() << " httptrans := trans.(*thrift.THttpClient)" << endl; - f_remote << indent() << " for key, value := range headers {" << endl; - f_remote << indent() << " httptrans.SetHeader(key, value)" << endl; - f_remote << indent() << " }" << endl; - f_remote << indent() << " }" << endl; - f_remote << indent() << "} else {" << endl; - f_remote << indent() << " portStr := fmt.Sprint(port)" << endl; - f_remote << indent() << " if strings.Contains(host, \":\") {" << endl; - f_remote << indent() << " host, portStr, err = net.SplitHostPort(host)" << endl; - f_remote << indent() << " if err != nil {" << endl; - f_remote << indent() << " fmt.Fprintln(os.Stderr, \"error with host:\", err)" - << endl; - f_remote << indent() << " os.Exit(1)" << endl; - f_remote << indent() << " }" << endl; - f_remote << indent() << " }" << endl; - f_remote << indent() << " trans = thrift.NewTSocketConf(net.JoinHostPort(host, portStr), cfg)" << endl; - f_remote << indent() << " if err != nil {" << endl; - f_remote << indent() << " fmt.Fprintln(os.Stderr, \"error resolving address:\", err)" << endl; - f_remote << indent() << " os.Exit(1)" << endl; - f_remote << indent() << " }" << endl; - f_remote << indent() << " if framed {" << endl; - f_remote << indent() << " trans = thrift.NewTFramedTransportConf(trans, cfg)" << endl; - f_remote << indent() << " }" << endl; - f_remote << indent() << "}" << endl; - f_remote << indent() << "if err != nil {" << endl; - f_remote << indent() << " fmt.Fprintln(os.Stderr, \"Error creating transport\", err)" << endl; - f_remote << indent() << " os.Exit(1)" << endl; - f_remote << indent() << "}" << endl; - f_remote << indent() << "defer trans.Close()" << endl; - f_remote << indent() << "var protocolFactory thrift.TProtocolFactory" << endl; - f_remote << indent() << "switch protocol {" << endl; - f_remote << indent() << "case \"compact\":" << endl; - f_remote << indent() << " protocolFactory = thrift.NewTCompactProtocolFactoryConf(cfg)" << endl; - f_remote << indent() << " break" << endl; - f_remote << indent() << "case \"simplejson\":" << endl; - f_remote << indent() << " protocolFactory = thrift.NewTSimpleJSONProtocolFactoryConf(cfg)" << endl; - f_remote << indent() << " break" << endl; - f_remote << indent() << "case \"json\":" << endl; - f_remote << indent() << " protocolFactory = thrift.NewTJSONProtocolFactory()" << endl; - f_remote << indent() << " break" << endl; - f_remote << indent() << "case \"binary\", \"\":" << endl; - f_remote << indent() << " protocolFactory = thrift.NewTBinaryProtocolFactoryConf(cfg)" << endl; - f_remote << indent() << " break" << endl; - f_remote << indent() << "default:" << endl; - f_remote << indent() << " fmt.Fprintln(os.Stderr, \"Invalid protocol specified: \", protocol)" - << endl; - f_remote << indent() << " Usage()" << endl; - f_remote << indent() << " os.Exit(1)" << endl; - f_remote << indent() << "}" << endl; - f_remote << indent() << "iprot := protocolFactory.GetProtocol(trans)" << endl; - f_remote << indent() << "oprot := protocolFactory.GetProtocol(trans)" << endl; + << '\n'; + f_remote << indent() << "flag.BoolVar(&useHttp, \"http\", false, \"Use http\")" << '\n'; + f_remote << indent() << "flag.Var(headers, \"H\", \"Headers to set on the http(s) request (e.g. -H \\\"Key: Value\\\")\")" << '\n'; + f_remote << indent() << "flag.Parse()" << '\n'; + f_remote << indent() << '\n'; + f_remote << indent() << "if len(urlString) > 0 {" << '\n'; + indent_up(); + f_remote << indent() << "var err error" << '\n'; + f_remote << indent() << "parsedUrl, err = url.Parse(urlString)" << '\n'; + f_remote << indent() << "if err != nil {" << '\n'; + indent_up(); + f_remote << indent() << "fmt.Fprintln(os.Stderr, \"Error parsing URL: \", err)" << '\n'; + f_remote << indent() << "flag.Usage()" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; + f_remote << indent() << "host = parsedUrl.Host" << '\n'; + f_remote << indent() << "useHttp = len(parsedUrl.Scheme) <= 0 || parsedUrl.Scheme == \"http\" || parsedUrl.Scheme == \"https\"" + << '\n'; + indent_down(); + f_remote << indent() << "} else if useHttp {" << '\n'; + indent_up(); + f_remote << indent() << "_, err := url.Parse(fmt.Sprint(\"http://\", host, \":\", port))" + << '\n'; + f_remote << indent() << "if err != nil {" << '\n'; + indent_up(); + f_remote << indent() << "fmt.Fprintln(os.Stderr, \"Error parsing URL: \", err)" << '\n'; + f_remote << indent() << "flag.Usage()" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; + f_remote << indent() << '\n'; + f_remote << indent() << "cmd := flag.Arg(0)" << '\n'; + f_remote << indent() << "var err error" << '\n'; + f_remote << indent() << "var cfg *thrift.TConfiguration = nil" << '\n'; + f_remote << indent() << "if useHttp {" << '\n'; + indent_up(); + f_remote << indent() << "trans, err = thrift.NewTHttpClient(parsedUrl.String())" << '\n'; + f_remote << indent() << "if len(headers) > 0 {" << '\n'; + indent_up(); + f_remote << indent() << "httptrans := trans.(*thrift.THttpClient)" << '\n'; + f_remote << indent() << "for key, value := range headers {" << '\n'; + indent_up(); + f_remote << indent() << "httptrans.SetHeader(key, value)" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; + indent_down(); + f_remote << indent() << "} else {" << '\n'; + indent_up(); + f_remote << indent() << "portStr := fmt.Sprint(port)" << '\n'; + f_remote << indent() << "if strings.Contains(host, \":\") {" << '\n'; + indent_up(); + f_remote << indent() << "host, portStr, err = net.SplitHostPort(host)" << '\n'; + f_remote << indent() << "if err != nil {" << '\n'; + indent_up(); + f_remote << indent() << "fmt.Fprintln(os.Stderr, \"error with host:\", err)" + << '\n'; + f_remote << indent() << "os.Exit(1)" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; + f_remote << indent() << "trans = thrift.NewTSocketConf(net.JoinHostPort(host, portStr), cfg)" << '\n'; + f_remote << indent() << "if err != nil {" << '\n'; + indent_up(); + f_remote << indent() << "fmt.Fprintln(os.Stderr, \"error resolving address:\", err)" << '\n'; + f_remote << indent() << "os.Exit(1)" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; + f_remote << indent() << "if framed {" << '\n'; + indent_up(); + f_remote << indent() << "trans = thrift.NewTFramedTransportConf(trans, cfg)" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; + f_remote << indent() << "if err != nil {" << '\n'; + indent_up(); + f_remote << indent() << "fmt.Fprintln(os.Stderr, \"Error creating transport\", err)" << '\n'; + f_remote << indent() << "os.Exit(1)" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; + f_remote << indent() << "defer trans.Close()" << '\n'; + f_remote << indent() << "var protocolFactory thrift.TProtocolFactory" << '\n'; + f_remote << indent() << "switch protocol {" << '\n'; + f_remote << indent() << "case \"compact\":" << '\n'; + indent_up(); + f_remote << indent() << "protocolFactory = thrift.NewTCompactProtocolFactoryConf(cfg)" << '\n'; + indent_down(); + f_remote << indent() << "case \"simplejson\":" << '\n'; + indent_up(); + f_remote << indent() << "protocolFactory = thrift.NewTSimpleJSONProtocolFactoryConf(cfg)" << '\n'; + indent_down(); + f_remote << indent() << "case \"json\":" << '\n'; + indent_up(); + f_remote << indent() << "protocolFactory = thrift.NewTJSONProtocolFactory()" << '\n'; + indent_down(); + f_remote << indent() << "case \"binary\", \"\":" << '\n'; + indent_up(); + f_remote << indent() << "protocolFactory = thrift.NewTBinaryProtocolFactoryConf(cfg)" << '\n'; + indent_down(); + f_remote << indent() << "default:" << '\n'; + indent_up(); + f_remote << indent() << "fmt.Fprintln(os.Stderr, \"Invalid protocol specified: \", protocol)" + << '\n'; + f_remote << indent() << "Usage()" << '\n'; + f_remote << indent() << "os.Exit(1)" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; + f_remote << indent() << "iprot := protocolFactory.GetProtocol(trans)" << '\n'; + f_remote << indent() << "oprot := protocolFactory.GetProtocol(trans)" << '\n'; f_remote << indent() << "client := " << package_name_aliased << ".New" << publicize(service_name_) - << "Client(thrift.NewTStandardClient(iprot, oprot))" << endl; - f_remote << indent() << "if err := trans.Open(); err != nil {" << endl; - f_remote << indent() << " fmt.Fprintln(os.Stderr, \"Error opening socket to \", " - "host, \":\", port, \" \", err)" << endl; - f_remote << indent() << " os.Exit(1)" << endl; - f_remote << indent() << "}" << endl; - f_remote << indent() << endl; - f_remote << indent() << "switch cmd {" << endl; + << "Client(thrift.NewTStandardClient(iprot, oprot))" << '\n'; + f_remote << indent() << "if err := trans.Open(); err != nil {" << '\n'; + indent_up(); + f_remote << indent() << "fmt.Fprintln(os.Stderr, \"Error opening socket to \", " + "host, \":\", port, \" \", err)" << '\n'; + f_remote << indent() << "os.Exit(1)" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; + f_remote << indent() << '\n'; + f_remote << indent() << "switch cmd {" << '\n'; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { t_struct* arg_struct = (*f_iter)->get_arglist(); @@ -2404,13 +2567,15 @@ void t_go_generator::generate_service_remote(t_service* tservice) { string funcName((*f_iter)->get_name()); string pubName(publicize(funcName)); string argumentsName(publicize(funcName + "_args", true, func_to_service[funcName])); - f_remote << indent() << "case \"" << escape_string(funcName) << "\":" << endl; + f_remote << indent() << "case \"" << escape_string(funcName) << "\":" << '\n'; + indent_up(); + f_remote << indent() << "if flag.NArg() - 1 != " << num_args << " {" << '\n'; indent_up(); - f_remote << indent() << "if flag.NArg() - 1 != " << num_args << " {" << endl; - f_remote << indent() << " fmt.Fprintln(os.Stderr, \"" << escape_string(pubName) << " requires " - << num_args << " args\")" << endl; - f_remote << indent() << " flag.Usage()" << endl; - f_remote << indent() << "}" << endl; + f_remote << indent() << "fmt.Fprintln(os.Stderr, \"" << escape_string(pubName) << " requires " + << num_args << " args\")" << '\n'; + f_remote << indent() << "flag.Usage()" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; for (std::vector::size_type i = 0; i < num_args; ++i) { std::vector::size_type flagArg = i + 1; @@ -2419,13 +2584,15 @@ void t_go_generator::generate_service_remote(t_service* tservice) { if (the_type2->is_enum()) { f_remote << indent() << "tmp" << i << ", err := (strconv.Atoi(flag.Arg(" << flagArg << ")))" - << endl; - f_remote << indent() << "if err != nil {" << endl; - f_remote << indent() << " Usage()" << endl; - f_remote << indent() << " return" << endl; - f_remote << indent() << "}" << endl; + << '\n'; + f_remote << indent() << "if err != nil {" << '\n'; + indent_up(); + f_remote << indent() << "Usage()" << '\n'; + f_remote << indent() << "return" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; f_remote << indent() << "argvalue" << i << " := " << package_name_aliased << "." - << publicize(the_type->get_name()) << "(tmp" << i << ")" << endl; + << publicize(the_type->get_name()) << "(tmp" << i << ")" << '\n'; } else if (the_type2->is_base_type()) { t_base_type::t_base e = ((t_base_type*)the_type2)->get_base(); string err(tmp("err")); @@ -2437,72 +2604,84 @@ void t_go_generator::generate_service_remote(t_service* tservice) { case t_base_type::TYPE_STRING: if (the_type2->is_binary()) { f_remote << indent() << "argvalue" << i << " := []byte(flag.Arg(" << flagArg << "))" - << endl; + << '\n'; } else { - f_remote << indent() << "argvalue" << i << " := flag.Arg(" << flagArg << ")" << endl; + f_remote << indent() << "argvalue" << i << " := flag.Arg(" << flagArg << ")" << '\n'; } break; case t_base_type::TYPE_BOOL: f_remote << indent() << "argvalue" << i << " := flag.Arg(" << flagArg << ") == \"true\"" - << endl; + << '\n'; break; case t_base_type::TYPE_I8: f_remote << indent() << "tmp" << i << ", " << err << " := (strconv.Atoi(flag.Arg(" - << flagArg << ")))" << endl; - f_remote << indent() << "if " << err << " != nil {" << endl; - f_remote << indent() << " Usage()" << endl; - f_remote << indent() << " return" << endl; - f_remote << indent() << "}" << endl; - f_remote << indent() << "argvalue" << i << " := int8(tmp" << i << ")" << endl; + << flagArg << ")))" << '\n'; + f_remote << indent() << "if " << err << " != nil {" << '\n'; + indent_up(); + f_remote << indent() << "Usage()" << '\n'; + f_remote << indent() << "return" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; + f_remote << indent() << "argvalue" << i << " := int8(tmp" << i << ")" << '\n'; break; case t_base_type::TYPE_I16: f_remote << indent() << "tmp" << i << ", " << err << " := (strconv.Atoi(flag.Arg(" - << flagArg << ")))" << endl; - f_remote << indent() << "if " << err << " != nil {" << endl; - f_remote << indent() << " Usage()" << endl; - f_remote << indent() << " return" << endl; - f_remote << indent() << "}" << endl; - f_remote << indent() << "argvalue" << i << " := int16(tmp" << i << ")" << endl; + << flagArg << ")))" << '\n'; + f_remote << indent() << "if " << err << " != nil {" << '\n'; + indent_up(); + f_remote << indent() << "Usage()" << '\n'; + f_remote << indent() << "return" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; + f_remote << indent() << "argvalue" << i << " := int16(tmp" << i << ")" << '\n'; break; case t_base_type::TYPE_I32: f_remote << indent() << "tmp" << i << ", " << err << " := (strconv.Atoi(flag.Arg(" - << flagArg << ")))" << endl; - f_remote << indent() << "if " << err << " != nil {" << endl; - f_remote << indent() << " Usage()" << endl; - f_remote << indent() << " return" << endl; - f_remote << indent() << "}" << endl; - f_remote << indent() << "argvalue" << i << " := int32(tmp" << i << ")" << endl; + << flagArg << ")))" << '\n'; + f_remote << indent() << "if " << err << " != nil {" << '\n'; + indent_up(); + f_remote << indent() << "Usage()" << '\n'; + f_remote << indent() << "return" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; + f_remote << indent() << "argvalue" << i << " := int32(tmp" << i << ")" << '\n'; break; case t_base_type::TYPE_I64: f_remote << indent() << "argvalue" << i << ", " << err - << " := (strconv.ParseInt(flag.Arg(" << flagArg << "), 10, 64))" << endl; - f_remote << indent() << "if " << err << " != nil {" << endl; - f_remote << indent() << " Usage()" << endl; - f_remote << indent() << " return" << endl; - f_remote << indent() << "}" << endl; + << " := (strconv.ParseInt(flag.Arg(" << flagArg << "), 10, 64))" << '\n'; + f_remote << indent() << "if " << err << " != nil {" << '\n'; + indent_up(); + f_remote << indent() << "Usage()" << '\n'; + f_remote << indent() << "return" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; break; case t_base_type::TYPE_DOUBLE: f_remote << indent() << "argvalue" << i << ", " << err - << " := (strconv.ParseFloat(flag.Arg(" << flagArg << "), 64))" << endl; - f_remote << indent() << "if " << err << " != nil {" << endl; - f_remote << indent() << " Usage()" << endl; - f_remote << indent() << " return" << endl; - f_remote << indent() << "}" << endl; + << " := (strconv.ParseFloat(flag.Arg(" << flagArg << "), 64))" << '\n'; + f_remote << indent() << "if " << err << " != nil {" << '\n'; + indent_up(); + f_remote << indent() << "Usage()" << '\n'; + f_remote << indent() << "return" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; break; case t_base_type::TYPE_UUID: f_remote << indent() << "argvalue" << i << ", " << err - << " := (thrift.ParseTuuid(flag.Arg(" << flagArg << ")))" << endl; - f_remote << indent() << "if " << err << " != nil {" << endl; - f_remote << indent() << " Usage()" << endl; - f_remote << indent() << " return" << endl; - f_remote << indent() << "}" << endl; + << " := (thrift.ParseTuuid(flag.Arg(" << flagArg << ")))" << '\n'; + f_remote << indent() << "if " << err << " != nil {" << '\n'; + indent_up(); + f_remote << indent() << "Usage()" << '\n'; + f_remote << indent() << "return" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; break; default: @@ -2524,26 +2703,30 @@ void t_go_generator::generate_service_remote(t_service* tservice) { tstruct_module = package_name_aliased; } - f_remote << indent() << arg << " := flag.Arg(" << flagArg << ")" << endl; + f_remote << indent() << arg << " := flag.Arg(" << flagArg << ")" << '\n'; f_remote << indent() << mbTrans << " := thrift.NewTMemoryBufferLen(len(" << arg << "))" - << endl; - f_remote << indent() << "defer " << mbTrans << ".Close()" << endl; + << '\n'; + f_remote << indent() << "defer " << mbTrans << ".Close()" << '\n'; f_remote << indent() << "_, " << err1 << " := " << mbTrans << ".WriteString(" << arg << ")" - << endl; - f_remote << indent() << "if " << err1 << " != nil {" << endl; - f_remote << indent() << " Usage()" << endl; - f_remote << indent() << " return" << endl; - f_remote << indent() << "}" << endl; - f_remote << indent() << factory << " := thrift.NewTJSONProtocolFactory()" << endl; + << '\n'; + f_remote << indent() << "if " << err1 << " != nil {" << '\n'; + indent_up(); + f_remote << indent() << "Usage()" << '\n'; + f_remote << indent() << "return" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; + f_remote << indent() << factory << " := thrift.NewTJSONProtocolFactory()" << '\n'; f_remote << indent() << jsProt << " := " << factory << ".GetProtocol(" << mbTrans << ")" - << endl; + << '\n'; f_remote << indent() << "argvalue" << i << " := " << tstruct_module << ".New" << tstruct_name - << "()" << endl; - f_remote << indent() << err2 << " := argvalue" << i << "." << read_method_name_ << "(context.Background(), " << jsProt << ")" << endl; - f_remote << indent() << "if " << err2 << " != nil {" << endl; - f_remote << indent() << " Usage()" << endl; - f_remote << indent() << " return" << endl; - f_remote << indent() << "}" << endl; + << "()" << '\n'; + f_remote << indent() << err2 << " := argvalue" << i << "." << read_method_name_ << "(context.Background(), " << jsProt << ")" << '\n'; + f_remote << indent() << "if " << err2 << " != nil {" << '\n'; + indent_up(); + f_remote << indent() << "Usage()" << '\n'; + f_remote << indent() << "return" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; } else if (the_type2->is_container() || the_type2->is_xception()) { string arg(tmp("arg")); string mbTrans(tmp("mbTrans")); @@ -2552,29 +2735,33 @@ void t_go_generator::generate_service_remote(t_service* tservice) { string jsProt(tmp("jsProt")); string err2(tmp("err")); std::string argName(publicize(args[i]->get_name())); - f_remote << indent() << arg << " := flag.Arg(" << flagArg << ")" << endl; + f_remote << indent() << arg << " := flag.Arg(" << flagArg << ")" << '\n'; f_remote << indent() << mbTrans << " := thrift.NewTMemoryBufferLen(len(" << arg << "))" - << endl; - f_remote << indent() << "defer " << mbTrans << ".Close()" << endl; + << '\n'; + f_remote << indent() << "defer " << mbTrans << ".Close()" << '\n'; f_remote << indent() << "_, " << err1 << " := " << mbTrans << ".WriteString(" << arg << ")" - << endl; - f_remote << indent() << "if " << err1 << " != nil { " << endl; - f_remote << indent() << " Usage()" << endl; - f_remote << indent() << " return" << endl; - f_remote << indent() << "}" << endl; - f_remote << indent() << factory << " := thrift.NewTJSONProtocolFactory()" << endl; + << '\n'; + f_remote << indent() << "if " << err1 << " != nil {" << '\n'; + indent_up(); + f_remote << indent() << "Usage()" << '\n'; + f_remote << indent() << "return" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; + f_remote << indent() << factory << " := thrift.NewTJSONProtocolFactory()" << '\n'; f_remote << indent() << jsProt << " := " << factory << ".GetProtocol(" << mbTrans << ")" - << endl; + << '\n'; f_remote << indent() << "containerStruct" << i << " := " << package_name_aliased << ".New" - << argumentsName << "()" << endl; + << argumentsName << "()" << '\n'; f_remote << indent() << err2 << " := containerStruct" << i << ".ReadField" << (i + 1) << "(context.Background(), " - << jsProt << ")" << endl; - f_remote << indent() << "if " << err2 << " != nil {" << endl; - f_remote << indent() << " Usage()" << endl; - f_remote << indent() << " return" << endl; - f_remote << indent() << "}" << endl; + << jsProt << ")" << '\n'; + f_remote << indent() << "if " << err2 << " != nil {" << '\n'; + indent_up(); + f_remote << indent() << "Usage()" << '\n'; + f_remote << indent() << "return" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; f_remote << indent() << "argvalue" << i << " := containerStruct" << i << "." << argName - << endl; + << '\n'; } else { throw("Invalid argument type in generate_service_remote"); } @@ -2585,9 +2772,9 @@ void t_go_generator::generate_service_remote(t_service* tservice) { typedef_module = package_name_aliased; } f_remote << indent() << "value" << i << " := " << typedef_module << "." - << publicize(the_type->get_name()) << "(argvalue" << i << ")" << endl; + << publicize(the_type->get_name()) << "(argvalue" << i << ")" << '\n'; } else { - f_remote << indent() << "value" << i << " := argvalue" << i << endl; + f_remote << indent() << "value" << i << " := argvalue" << i << '\n'; } } @@ -2634,20 +2821,23 @@ void t_go_generator::generate_service_remote(t_service* tservice) { } } - f_remote << "))" << endl; - f_remote << indent() << "fmt.Print(\"\\n\")" << endl; - f_remote << indent() << "break" << endl; + f_remote << "))" << '\n'; + f_remote << indent() << "fmt.Print(\"\\n\")" << '\n'; + f_remote << indent() << "break" << '\n'; indent_down(); } - f_remote << indent() << "case \"\":" << endl; - f_remote << indent() << " Usage()" << endl; - f_remote << indent() << " break" << endl; - f_remote << indent() << "default:" << endl; - f_remote << indent() << " fmt.Fprintln(os.Stderr, \"Invalid function \", cmd)" << endl; - f_remote << indent() << "}" << endl; + f_remote << indent() << "case \"\":" << '\n'; + indent_up(); + f_remote << indent() << "Usage()" << '\n'; + indent_down(); + f_remote << indent() << "default:" << '\n'; + indent_up(); + f_remote << indent() << "fmt.Fprintln(os.Stderr, \"Invalid function \", cmd)" << '\n'; indent_down(); - f_remote << indent() << "}" << endl; + f_remote << indent() << "}" << '\n'; + indent_down(); + f_remote << indent() << "}" << '\n'; // Close service file f_remote.close(); format_go_output(f_remote_name); @@ -2696,80 +2886,99 @@ void t_go_generator::generate_service_server(t_service* tservice) { string self(tmp("self")); if (extends_processor.empty()) { - f_types_ << indent() << "type " << serviceName << "Processor struct {" << endl; - f_types_ << indent() << " processorMap map[string]thrift.TProcessorFunction" << endl; - f_types_ << indent() << " handler " << serviceName << endl; - f_types_ << indent() << "}" << endl << endl; + generate_deprecation_comment(f_types_, tservice->annotations_); + f_types_ << indent() << "type " << serviceName << "Processor struct {" << '\n'; + indent_up(); + f_types_ << indent() << "processorMap map[string]thrift.TProcessorFunction" << '\n'; + f_types_ << indent() << "handler " << serviceName << '\n'; + indent_down(); + f_types_ << indent() << "}" << '\n' << '\n'; f_types_ << indent() << "func (p *" << serviceName << "Processor) AddToProcessorMap(key string, processor thrift.TProcessorFunction) {" - << endl; - f_types_ << indent() << " p.processorMap[key] = processor" << endl; - f_types_ << indent() << "}" << endl << endl; + << '\n'; + indent_up(); + f_types_ << indent() << "p.processorMap[key] = processor" << '\n'; + indent_down(); + f_types_ << indent() << "}" << '\n' << '\n'; f_types_ << indent() << "func (p *" << serviceName << "Processor) GetProcessorFunction(key string) " - "(processor thrift.TProcessorFunction, ok bool) {" << endl; - f_types_ << indent() << " processor, ok = p.processorMap[key]" << endl; - f_types_ << indent() << " return processor, ok" << endl; - f_types_ << indent() << "}" << endl << endl; + "(processor thrift.TProcessorFunction, ok bool) {" << '\n'; + indent_up(); + f_types_ << indent() << "processor, ok = p.processorMap[key]" << '\n'; + f_types_ << indent() << "return processor, ok" << '\n'; + indent_down(); + f_types_ << indent() << "}" << '\n' << '\n'; f_types_ << indent() << "func (p *" << serviceName - << "Processor) ProcessorMap() map[string]thrift.TProcessorFunction {" << endl; - f_types_ << indent() << " return p.processorMap" << endl; - f_types_ << indent() << "}" << endl << endl; + << "Processor) ProcessorMap() map[string]thrift.TProcessorFunction {" << '\n'; + indent_up(); + f_types_ << indent() << "return p.processorMap" << '\n'; + indent_down(); + f_types_ << indent() << "}" << '\n' << '\n'; + generate_deprecation_comment(f_types_, tservice->annotations_); f_types_ << indent() << "func New" << serviceName << "Processor(handler " << serviceName - << ") *" << serviceName << "Processor {" << endl << endl; + << ") *" << serviceName << "Processor {" << '\n' << '\n'; + indent_up(); f_types_ - << indent() << " " << self << " := &" << serviceName + << indent() << self << " := &" << serviceName << "Processor{handler:handler, processorMap:make(map[string]thrift.TProcessorFunction)}" - << endl; + << '\n'; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { string escapedFuncName(escape_string((*f_iter)->get_name())); - f_types_ << indent() << " " << self << ".processorMap[\"" << escapedFuncName << "\"] = &" + f_types_ << indent() << self << ".processorMap[\"" << escapedFuncName << "\"] = &" << pServiceName << "Processor" << publicize((*f_iter)->get_name()) - << "{handler:handler}" << endl; + << "{handler:handler}" << '\n'; } string x(tmp("x")); - f_types_ << indent() << "return " << self << endl; - f_types_ << indent() << "}" << endl << endl; + f_types_ << indent() << "return " << self << '\n'; + indent_down(); + f_types_ << indent() << "}" << '\n' << '\n'; f_types_ << indent() << "func (p *" << serviceName << "Processor) Process(ctx context.Context, iprot, oprot thrift.TProtocol) (success bool, err " - "thrift.TException) {" << endl; - f_types_ << indent() << " name, _, seqId, err2 := iprot.ReadMessageBegin(ctx)" << endl; - f_types_ << indent() << " if err2 != nil { return false, thrift.WrapTException(err2) }" << endl; - f_types_ << indent() << " if processor, ok := p.GetProcessorFunction(name); ok {" << endl; - f_types_ << indent() << " return processor.Process(ctx, seqId, iprot, oprot)" << endl; - f_types_ << indent() << " }" << endl; - f_types_ << indent() << " iprot.Skip(ctx, thrift.STRUCT)" << endl; - f_types_ << indent() << " iprot.ReadMessageEnd(ctx)" << endl; - f_types_ << indent() << " " << x + "thrift.TException) {" << '\n'; + indent_up(); + f_types_ << indent() << "name, _, seqId, err2 := iprot.ReadMessageBegin(ctx)" << '\n'; + f_types_ << indent() << "if err2 != nil { return false, thrift.WrapTException(err2) }" << '\n'; + f_types_ << indent() << "if processor, ok := p.GetProcessorFunction(name); ok {" << '\n'; + indent_up(); + f_types_ << indent() << "return processor.Process(ctx, seqId, iprot, oprot)" << '\n'; + indent_down(); + f_types_ << indent() << "}" << '\n'; + f_types_ << indent() << "iprot.Skip(ctx, thrift.STRUCT)" << '\n'; + f_types_ << indent() << "iprot.ReadMessageEnd(ctx)" << '\n'; + f_types_ << indent() << "" << x << " := thrift.NewTApplicationException(thrift.UNKNOWN_METHOD, \"Unknown function " - "\" + name)" << endl; - f_types_ << indent() << " oprot.WriteMessageBegin(ctx, name, thrift.EXCEPTION, seqId)" << endl; - f_types_ << indent() << " " << x << ".Write(ctx, oprot)" << endl; - f_types_ << indent() << " oprot.WriteMessageEnd(ctx)" << endl; - f_types_ << indent() << " oprot.Flush(ctx)" << endl; - f_types_ << indent() << " return false, " << x << endl; - f_types_ << indent() << "" << endl; - f_types_ << indent() << "}" << endl << endl; + "\" + name)" << '\n'; + f_types_ << indent() << "oprot.WriteMessageBegin(ctx, name, thrift.EXCEPTION, seqId)" << '\n'; + f_types_ << indent() << "" << x << ".Write(ctx, oprot)" << '\n'; + f_types_ << indent() << "oprot.WriteMessageEnd(ctx)" << '\n'; + f_types_ << indent() << "oprot.Flush(ctx)" << '\n'; + f_types_ << indent() << "return false, " << x << '\n'; + indent_down(); + f_types_ << indent() << "}" << '\n' << '\n'; } else { - f_types_ << indent() << "type " << serviceName << "Processor struct {" << endl; - f_types_ << indent() << " *" << extends_processor << endl; - f_types_ << indent() << "}" << endl << endl; + f_types_ << indent() << "type " << serviceName << "Processor struct {" << '\n'; + indent_up(); + f_types_ << indent() << "*" << extends_processor << '\n'; + indent_down(); + f_types_ << indent() << "}" << '\n' << '\n'; f_types_ << indent() << "func New" << serviceName << "Processor(handler " << serviceName - << ") *" << serviceName << "Processor {" << endl; - f_types_ << indent() << " " << self << " := &" << serviceName << "Processor{" - << extends_processor_new << "(handler)}" << endl; + << ") *" << serviceName << "Processor {" << '\n'; + indent_up(); + f_types_ << indent() << self << " := &" << serviceName << "Processor{" + << extends_processor_new << "(handler)}" << '\n'; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { string escapedFuncName(escape_string((*f_iter)->get_name())); - f_types_ << indent() << " " << self << ".AddToProcessorMap(\"" << escapedFuncName + f_types_ << indent() << self << ".AddToProcessorMap(\"" << escapedFuncName << "\", &" << pServiceName << "Processor" << publicize((*f_iter)->get_name()) - << "{handler:handler})" << endl; + << "{handler:handler})" << '\n'; } - f_types_ << indent() << " return " << self << endl; - f_types_ << indent() << "}" << endl << endl; + f_types_ << indent() << "return " << self << '\n'; + indent_down(); + f_types_ << indent() << "}" << '\n' << '\n'; } // Generate the process subfunctions @@ -2777,7 +2986,7 @@ void t_go_generator::generate_service_server(t_service* tservice) { generate_process_function(tservice, *f_iter); } - f_types_ << endl; + f_types_ << '\n'; } /** @@ -2794,90 +3003,92 @@ void t_go_generator::generate_process_function(t_service* tservice, t_function* // t_struct* xs = tfunction->get_xceptions(); // const std::vector& xceptions = xs->get_members(); - f_types_ << indent() << "type " << processorName << " struct {" << endl; - f_types_ << indent() << " handler " << publicize(tservice->get_name()) << endl; - f_types_ << indent() << "}" << endl << endl; + f_types_ << indent() << "type " << processorName << " struct {" << '\n'; + indent_up(); + f_types_ << indent() << "handler " << publicize(tservice->get_name()) << '\n'; + indent_down(); + f_types_ << indent() << "}" << '\n' << '\n'; f_types_ << indent() << "func (p *" << processorName << ") Process(ctx context.Context, seqId int32, iprot, oprot thrift.TProtocol) (success bool, err " - "thrift.TException) {" << endl; + "thrift.TException) {" << '\n'; indent_up(); string write_err; if (!tfunction->is_oneway()) { write_err = tmp("_write_err"); - f_types_ << indent() << "var " << write_err << " error" << endl; + f_types_ << indent() << "var " << write_err << " thrift.TException" << '\n'; } - f_types_ << indent() << "args := " << argsname << "{}" << endl; - f_types_ << indent() << "if err2 := args." << read_method_name_ << "(ctx, iprot); err2 != nil {" << endl; + f_types_ << indent() << "args := " << argsname << "{}" << '\n'; + f_types_ << indent() << "if err2 := args." << read_method_name_ << "(ctx, iprot); err2 != nil {" << '\n'; indent_up(); - f_types_ << indent() << "iprot.ReadMessageEnd(ctx)" << endl; + f_types_ << indent() << "iprot.ReadMessageEnd(ctx)" << '\n'; if (!tfunction->is_oneway()) { f_types_ << indent() << "x := thrift.NewTApplicationException(thrift.PROTOCOL_ERROR, err2.Error())" - << endl; + << '\n'; f_types_ << indent() << "oprot.WriteMessageBegin(ctx, \"" << escape_string(tfunction->get_name()) - << "\", thrift.EXCEPTION, seqId)" << endl; - f_types_ << indent() << "x.Write(ctx, oprot)" << endl; - f_types_ << indent() << "oprot.WriteMessageEnd(ctx)" << endl; - f_types_ << indent() << "oprot.Flush(ctx)" << endl; + << "\", thrift.EXCEPTION, seqId)" << '\n'; + f_types_ << indent() << "x.Write(ctx, oprot)" << '\n'; + f_types_ << indent() << "oprot.WriteMessageEnd(ctx)" << '\n'; + f_types_ << indent() << "oprot.Flush(ctx)" << '\n'; } - f_types_ << indent() << "return false, thrift.WrapTException(err2)" << endl; + f_types_ << indent() << "return false, thrift.WrapTException(err2)" << '\n'; indent_down(); - f_types_ << indent() << "}" << endl; - f_types_ << indent() << "iprot.ReadMessageEnd(ctx)" << endl << endl; + f_types_ << indent() << "}" << '\n'; + f_types_ << indent() << "iprot.ReadMessageEnd(ctx)" << '\n' << '\n'; // Even though we never create the goroutine in oneway handlers, // always have (nop) tickerCancel defined makes the writing part of code // generating easier and less error-prone. - f_types_ << indent() << "tickerCancel := func() {}" << endl; + f_types_ << indent() << "tickerCancel := func() {}" << '\n'; // Only create the goroutine for non-oneways. if (!tfunction->is_oneway()) { - f_types_ << indent() << "// Start a goroutine to do server side connectivity check." << endl; - f_types_ << indent() << "if thrift.ServerConnectivityCheckInterval > 0 {" << endl; + f_types_ << indent() << "// Start a goroutine to do server side connectivity check." << '\n'; + f_types_ << indent() << "if thrift.ServerConnectivityCheckInterval > 0 {" << '\n'; indent_up(); - f_types_ << indent() << "var cancel context.CancelCauseFunc" << endl; - f_types_ << indent() << "ctx, cancel = context.WithCancelCause(ctx)" << endl; - f_types_ << indent() << "defer cancel(nil)" << endl; - f_types_ << indent() << "var tickerCtx context.Context" << endl; - f_types_ << indent() << "tickerCtx, tickerCancel = context.WithCancel(context.Background())" << endl; - f_types_ << indent() << "defer tickerCancel()" << endl; - f_types_ << indent() << "go func(ctx context.Context, cancel context.CancelCauseFunc) {" << endl; + f_types_ << indent() << "var cancel context.CancelCauseFunc" << '\n'; + f_types_ << indent() << "ctx, cancel = context.WithCancelCause(ctx)" << '\n'; + f_types_ << indent() << "defer cancel(nil)" << '\n'; + f_types_ << indent() << "var tickerCtx context.Context" << '\n'; + f_types_ << indent() << "tickerCtx, tickerCancel = context.WithCancel(context.Background())" << '\n'; + f_types_ << indent() << "defer tickerCancel()" << '\n'; + f_types_ << indent() << "go func(ctx context.Context, cancel context.CancelCauseFunc) {" << '\n'; indent_up(); - f_types_ << indent() << "ticker := time.NewTicker(thrift.ServerConnectivityCheckInterval)" << endl; - f_types_ << indent() << "defer ticker.Stop()" << endl; - f_types_ << indent() << "for {" << endl; + f_types_ << indent() << "ticker := time.NewTicker(thrift.ServerConnectivityCheckInterval)" << '\n'; + f_types_ << indent() << "defer ticker.Stop()" << '\n'; + f_types_ << indent() << "for {" << '\n'; indent_up(); - f_types_ << indent() << "select {" << endl; - f_types_ << indent() << "case <-ctx.Done():" << endl; + f_types_ << indent() << "select {" << '\n'; + f_types_ << indent() << "case <-ctx.Done():" << '\n'; indent_up(); - f_types_ << indent() << "return" << endl; + f_types_ << indent() << "return" << '\n'; indent_down(); - f_types_ << indent() << "case <-ticker.C:" << endl; + f_types_ << indent() << "case <-ticker.C:" << '\n'; indent_up(); - f_types_ << indent() << "if !iprot.Transport().IsOpen() {" << endl; + f_types_ << indent() << "if !iprot.Transport().IsOpen() {" << '\n'; indent_up(); - f_types_ << indent() << "cancel(thrift.ErrAbandonRequest)" << endl; - f_types_ << indent() << "return" << endl; + f_types_ << indent() << "cancel(thrift.ErrAbandonRequest)" << '\n'; + f_types_ << indent() << "return" << '\n'; indent_down(); - f_types_ << indent() << "}" << endl; + f_types_ << indent() << "}" << '\n'; indent_down(); - f_types_ << indent() << "}" << endl; + f_types_ << indent() << "}" << '\n'; indent_down(); - f_types_ << indent() << "}" << endl; + f_types_ << indent() << "}" << '\n'; indent_down(); - f_types_ << indent() << "}(tickerCtx, cancel)" << endl; + f_types_ << indent() << "}(tickerCtx, cancel)" << '\n'; indent_down(); - f_types_ << indent() << "}" << endl << endl; + f_types_ << indent() << "}" << '\n' << '\n'; } else { // Make sure we don't get the defined but unused compiling error. - f_types_ << indent() << "_ = tickerCancel" << endl << endl; + f_types_ << indent() << "_ = tickerCancel" << '\n' << '\n'; } if (!tfunction->is_oneway()) { - f_types_ << indent() << "result := " << resultname << "{}" << endl; + f_types_ << indent() << "result := " << resultname << "{}" << '\n'; } bool need_reference = type_need_reference(tfunction->get_returntype()); @@ -2908,93 +3119,108 @@ void t_go_generator::generate_process_function(t_service* tservice, t_function* f_types_ << "args." << publicize((*f_iter)->get_name()); } - f_types_ << "); err2 != nil {" << endl; + f_types_ << "); err2 != nil {" << '\n'; indent_up(); - f_types_ << indent() << "tickerCancel()" << endl; - f_types_ << indent() << "err = thrift.WrapTException(err2)" << endl; + f_types_ << indent() << "tickerCancel()" << '\n'; + f_types_ << indent() << "err = thrift.WrapTException(err2)" << '\n'; t_struct* exceptions = tfunction->get_xceptions(); const vector& x_fields = exceptions->get_members(); if (!x_fields.empty()) { - f_types_ << indent() << "switch v := err2.(type) {" << endl; + f_types_ << indent() << "switch v := err2.(type) {" << '\n'; vector::const_iterator xf_iter; for (xf_iter = x_fields.begin(); xf_iter != x_fields.end(); ++xf_iter) { f_types_ << indent() << "case " << type_to_go_type(((*xf_iter)->get_type())) << ":" - << endl; + << '\n'; indent_up(); - f_types_ << indent() << "result." << publicize((*xf_iter)->get_name()) << " = v" << endl; + f_types_ << indent() << "result." << publicize((*xf_iter)->get_name()) << " = v" << '\n'; indent_down(); } - f_types_ << indent() << "default:" << endl; + f_types_ << indent() << "default:" << '\n'; indent_up(); } if (!tfunction->is_oneway()) { // Avoid writing the error to the wire if it's ErrAbandonRequest - f_types_ << indent() << "if errors.Is(err2, thrift.ErrAbandonRequest) {" << endl; + f_types_ << indent() << "if errors.Is(err2, thrift.ErrAbandonRequest) {" << '\n'; indent_up(); - f_types_ << indent() << "return false, thrift.WrapTException(err2)" << endl; + f_types_ << indent() << "return false, &thrift.ProcessorError{" << '\n'; + indent_up(); + f_types_ << indent() << "WriteError: thrift.WrapTException(err2)," << '\n'; + f_types_ << indent() << "EndpointError: err," << '\n'; + indent_down(); + f_types_ << indent() << "}" << '\n'; indent_down(); - f_types_ << indent() << "}" << endl; - f_types_ << indent() << "if errors.Is(err2, context.Canceled) {" << endl; + f_types_ << indent() << "}" << '\n'; + f_types_ << indent() << "if errors.Is(err2, context.Canceled) {" << '\n'; indent_up(); - f_types_ << indent() << "if err := context.Cause(ctx); errors.Is(err, thrift.ErrAbandonRequest) {" << endl; + f_types_ << indent() << "if err3 := context.Cause(ctx); errors.Is(err3, thrift.ErrAbandonRequest) {" << '\n'; indent_up(); - f_types_ << indent() << "return false, thrift.WrapTException(err)" << endl; + f_types_ << indent() << "return false, &thrift.ProcessorError{" << '\n'; + indent_up(); + f_types_ << indent() << "WriteError: thrift.WrapTException(err3)," << '\n'; + f_types_ << indent() << "EndpointError: err," << '\n'; + indent_down(); + f_types_ << indent() << "}" << '\n'; indent_down(); - f_types_ << indent() << "}" << endl; + f_types_ << indent() << "}" << '\n'; indent_down(); - f_types_ << indent() << "}" << endl; + f_types_ << indent() << "}" << '\n'; string exc(tmp("_exc")); f_types_ << indent() << exc << " := thrift.NewTApplicationException(thrift.INTERNAL_ERROR, " "\"Internal error processing " << escape_string(tfunction->get_name()) - << ": \" + err2.Error())" << endl; + << ": \" + err2.Error())" << '\n'; f_types_ << indent() << "if err2 := oprot.WriteMessageBegin(ctx, \"" << escape_string(tfunction->get_name()) - << "\", thrift.EXCEPTION, seqId); err2 != nil {" << endl; + << "\", thrift.EXCEPTION, seqId); err2 != nil {" << '\n'; indent_up(); - f_types_ << indent() << write_err << " = thrift.WrapTException(err2)" << endl; + f_types_ << indent() << write_err << " = thrift.WrapTException(err2)" << '\n'; indent_down(); - f_types_ << indent() << "}" << endl; + f_types_ << indent() << "}" << '\n'; f_types_ << indent() << "if err2 := " << exc << ".Write(ctx, oprot); " - << write_err << " == nil && err2 != nil {" << endl; + << write_err << " == nil && err2 != nil {" << '\n'; indent_up(); - f_types_ << indent() << write_err << " = thrift.WrapTException(err2)" << endl; + f_types_ << indent() << write_err << " = thrift.WrapTException(err2)" << '\n'; indent_down(); - f_types_ << indent() << "}" << endl; + f_types_ << indent() << "}" << '\n'; f_types_ << indent() << "if err2 := oprot.WriteMessageEnd(ctx); " - << write_err << " == nil && err2 != nil {" << endl; + << write_err << " == nil && err2 != nil {" << '\n'; indent_up(); - f_types_ << indent() << write_err << " = thrift.WrapTException(err2)" << endl; + f_types_ << indent() << write_err << " = thrift.WrapTException(err2)" << '\n'; indent_down(); - f_types_ << indent() << "}" << endl; + f_types_ << indent() << "}" << '\n'; f_types_ << indent() << "if err2 := oprot.Flush(ctx); " - << write_err << " == nil && err2 != nil {" << endl; + << write_err << " == nil && err2 != nil {" << '\n'; indent_up(); - f_types_ << indent() << write_err << " = thrift.WrapTException(err2)" << endl; + f_types_ << indent() << write_err << " = thrift.WrapTException(err2)" << '\n'; indent_down(); - f_types_ << indent() << "}" << endl; + f_types_ << indent() << "}" << '\n'; - f_types_ << indent() << "if " << write_err << " != nil {" << endl; + f_types_ << indent() << "if " << write_err << " != nil {" << '\n'; indent_up(); - f_types_ << indent() << "return false, thrift.WrapTException(" << write_err << ")" << endl; + f_types_ << indent() << "return false, &thrift.ProcessorError{" << '\n'; + indent_up(); + f_types_ << indent() << "WriteError: " << write_err << "," << '\n'; + f_types_ << indent() << "EndpointError: err," << '\n'; + indent_down(); + f_types_ << indent() << "}" << '\n'; indent_down(); - f_types_ << indent() << "}" << endl; + f_types_ << indent() << "}" << '\n'; // return success=true as long as writing to the wire was successful. - f_types_ << indent() << "return true, err" << endl; + f_types_ << indent() << "return true, err" << '\n'; } if (!x_fields.empty()) { indent_down(); - f_types_ << indent() << "}" << endl; // closes switch + f_types_ << indent() << "}" << '\n'; // closes switch } indent_down(); @@ -3002,63 +3228,68 @@ void t_go_generator::generate_process_function(t_service* tservice, t_function* if (!tfunction->is_oneway()) { if (!tfunction->get_returntype()->is_void()) { - f_types_ << " else {" << endl; // make sure we set Success retval only on success + f_types_ << " else {" << '\n'; // make sure we set Success retval only on success indent_up(); f_types_ << indent() << "result.Success = "; if (need_reference) { f_types_ << "&"; } - f_types_ << "retval" << endl; + f_types_ << "retval" << '\n'; indent_down(); - f_types_ << indent() << "}" << endl; + f_types_ << indent() << "}" << '\n'; } else { - f_types_ << endl; + f_types_ << '\n'; } - f_types_ << indent() << "tickerCancel()" << endl; + f_types_ << indent() << "tickerCancel()" << '\n'; f_types_ << indent() << "if err2 := oprot.WriteMessageBegin(ctx, \"" << escape_string(tfunction->get_name()) << "\", thrift.REPLY, seqId); err2 != nil {" - << endl; + << '\n'; indent_up(); - f_types_ << indent() << write_err << " = thrift.WrapTException(err2)" << endl; + f_types_ << indent() << write_err << " = thrift.WrapTException(err2)" << '\n'; indent_down(); - f_types_ << indent() << "}" << endl; + f_types_ << indent() << "}" << '\n'; f_types_ << indent() << "if err2 := result." << write_method_name_ << "(ctx, oprot); " - << write_err << " == nil && err2 != nil {" << endl; + << write_err << " == nil && err2 != nil {" << '\n'; indent_up(); - f_types_ << indent() << write_err << " = thrift.WrapTException(err2)" << endl; + f_types_ << indent() << write_err << " = thrift.WrapTException(err2)" << '\n'; indent_down(); - f_types_ << indent() << "}" << endl; + f_types_ << indent() << "}" << '\n'; f_types_ << indent() << "if err2 := oprot.WriteMessageEnd(ctx); " - << write_err << " == nil && err2 != nil {" << endl; + << write_err << " == nil && err2 != nil {" << '\n'; indent_up(); - f_types_ << indent() << write_err << " = thrift.WrapTException(err2)" << endl; + f_types_ << indent() << write_err << " = thrift.WrapTException(err2)" << '\n'; indent_down(); - f_types_ << indent() << "}" << endl; + f_types_ << indent() << "}" << '\n'; - f_types_ << indent() << "if err2 := oprot.Flush(ctx); " << write_err << " == nil && err2 != nil {" << endl; + f_types_ << indent() << "if err2 := oprot.Flush(ctx); " << write_err << " == nil && err2 != nil {" << '\n'; indent_up(); - f_types_ << indent() << write_err << " = thrift.WrapTException(err2)" << endl; + f_types_ << indent() << write_err << " = thrift.WrapTException(err2)" << '\n'; indent_down(); - f_types_ << indent() << "}" << endl; + f_types_ << indent() << "}" << '\n'; - f_types_ << indent() << "if " << write_err << " != nil {" << endl; + f_types_ << indent() << "if " << write_err << " != nil {" << '\n'; + indent_up(); + f_types_ << indent() << "return false, &thrift.ProcessorError{" << '\n'; indent_up(); - f_types_ << indent() << "return false, thrift.WrapTException(" << write_err << ")" << endl; + f_types_ << indent() << "WriteError: " << write_err << "," << '\n'; + f_types_ << indent() << "EndpointError: err," << '\n'; indent_down(); - f_types_ << indent() << "}" << endl; + f_types_ << indent() << "}" << '\n'; + indent_down(); + f_types_ << indent() << "}" << '\n'; // return success=true as long as writing to the wire was successful. - f_types_ << indent() << "return true, err" << endl; + f_types_ << indent() << "return true, err" << '\n'; } else { - f_types_ << endl; - f_types_ << indent() << "tickerCancel()" << endl; - f_types_ << indent() << "return true, err" << endl; + f_types_ << '\n'; + f_types_ << indent() << "tickerCancel()" << '\n'; + f_types_ << indent() << "return true, err" << '\n'; } indent_down(); - f_types_ << indent() << "}" << endl << endl; + f_types_ << indent() << "}" << '\n' << '\n'; } /** @@ -3096,7 +3327,7 @@ void t_go_generator::generate_deserialize_field(ostream& out, string type_name = inkey ? type_to_go_key_type(tfield->get_type()) : type_to_go_type(tfield->get_type()); - out << "var " << tfield->get_name() << " " << type_name << endl; + out << indent() << "var " << tfield->get_name() << " " << type_name << '\n'; } indent(out) << "if v, err := iprot."; @@ -3153,11 +3384,14 @@ void t_go_generator::generate_deserialize_field(ostream& out, out << "ReadI32(ctx)"; } - out << "; err != nil {" << endl; + out << "; err != nil {" << '\n'; + indent_up(); out << indent() << "return thrift.PrependError(\"error reading field " << tfield->get_key() - << ": \", err)" << endl; + << ": \", err)" << '\n'; - out << "} else {" << endl; + indent_down(); + out << indent() << "} else {" << '\n'; + indent_up(); string wrap; if (type->is_enum() || orig_type->is_typedef()) { @@ -3168,13 +3402,14 @@ void t_go_generator::generate_deserialize_field(ostream& out, string maybe_address = (is_pointer_field(tfield) ? "&" : ""); if (wrap == "") { - indent(out) << name << " = " << maybe_address << "v" << endl; + indent(out) << name << " = " << maybe_address << "v" << '\n'; } else { - indent(out) << "temp := " << wrap << "(v)" << endl; - indent(out) << name << " = " << maybe_address << "temp" << endl; + indent(out) << "temp := " << wrap << "(v)" << '\n'; + indent(out) << name << " = " << maybe_address << "temp" << '\n'; } - out << "}" << endl; + indent_down(); + out << indent() << "}" << '\n'; } else { throw "INVALID TYPE IN generate_deserialize_field '" + type->get_name() + "' for field '" + tfield->get_name() + "'"; @@ -3193,10 +3428,12 @@ void t_go_generator::generate_deserialize_struct(ostream& out, out << indent() << prefix << eq << (pointer_field ? "&" : ""); generate_go_struct_initializer(out, tstruct); - out << indent() << "if err := " << prefix << "." << read_method_name_ << "(ctx, iprot); err != nil {" << endl; - out << indent() << " return thrift.PrependError(fmt.Sprintf(\"%T error reading struct: \", " - << prefix << "), err)" << endl; - out << indent() << "}" << endl; + out << indent() << "if err := " << prefix << "." << read_method_name_ << "(ctx, iprot); err != nil {" << '\n'; + indent_up(); + out << indent() << "return thrift.PrependError(fmt.Sprintf(\"%T error reading struct: \", " + << prefix << "), err)" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; } /** @@ -3217,33 +3454,39 @@ void t_go_generator::generate_deserialize_container(ostream& out, // Declare variables, read header if (ttype->is_map()) { - out << indent() << "_, _, size, err := iprot.ReadMapBegin(ctx)" << endl; - out << indent() << "if err != nil {" << endl; - out << indent() << " return thrift.PrependError(\"error reading map begin: \", err)" << endl; - out << indent() << "}" << endl; - out << indent() << "tMap := make(" << type_to_go_type(orig_type) << ", size)" << endl; - out << indent() << prefix << eq << " " << (pointer_field ? "&" : "") << "tMap" << endl; + out << indent() << "_, _, size, err := iprot.ReadMapBegin(ctx)" << '\n'; + out << indent() << "if err != nil {" << '\n'; + indent_up(); + out << indent() << "return thrift.PrependError(\"error reading map begin: \", err)" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; + out << indent() << "tMap := make(" << type_to_go_type(orig_type) << ", size)" << '\n'; + out << indent() << prefix << eq << (pointer_field ? "&" : "") << "tMap" << '\n'; } else if (ttype->is_set()) { - out << indent() << "_, size, err := iprot.ReadSetBegin(ctx)" << endl; - out << indent() << "if err != nil {" << endl; - out << indent() << " return thrift.PrependError(\"error reading set begin: \", err)" << endl; - out << indent() << "}" << endl; - out << indent() << "tSet := make(" << type_to_go_type(orig_type) << ", 0, size)" << endl; - out << indent() << prefix << eq << " " << (pointer_field ? "&" : "") << "tSet" << endl; + out << indent() << "_, size, err := iprot.ReadSetBegin(ctx)" << '\n'; + out << indent() << "if err != nil {" << '\n'; + indent_up(); + out << indent() << "return thrift.PrependError(\"error reading set begin: \", err)" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; + out << indent() << "tSet := make(" << type_to_go_type(orig_type) << ", 0, size)" << '\n'; + out << indent() << prefix << eq << (pointer_field ? "&" : "") << "tSet" << '\n'; } else if (ttype->is_list()) { - out << indent() << "_, size, err := iprot.ReadListBegin(ctx)" << endl; - out << indent() << "if err != nil {" << endl; - out << indent() << " return thrift.PrependError(\"error reading list begin: \", err)" << endl; - out << indent() << "}" << endl; - out << indent() << "tSlice := make(" << type_to_go_type(orig_type) << ", 0, size)" << endl; - out << indent() << prefix << eq << " " << (pointer_field ? "&" : "") << "tSlice" << endl; + out << indent() << "_, size, err := iprot.ReadListBegin(ctx)" << '\n'; + out << indent() << "if err != nil {" << '\n'; + indent_up(); + out << indent() << "return thrift.PrependError(\"error reading list begin: \", err)" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; + out << indent() << "tSlice := make(" << type_to_go_type(orig_type) << ", 0, size)" << '\n'; + out << indent() << prefix << eq << (pointer_field ? "&" : "") << "tSlice" << '\n'; } else { throw "INVALID TYPE IN generate_deserialize_container '" + ttype->get_name() + "' for prefix '" + prefix + "'"; } // For loop iterates over elements - out << indent() << "for i := 0; i < size; i ++ {" << endl; + out << indent() << "for i := 0; i < size; i++ {" << '\n'; indent_up(); if (pointer_field) { @@ -3258,21 +3501,27 @@ void t_go_generator::generate_deserialize_container(ostream& out, } indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; // Read container end if (ttype->is_map()) { - out << indent() << "if err := iprot.ReadMapEnd(ctx); err != nil {" << endl; - out << indent() << " return thrift.PrependError(\"error reading map end: \", err)" << endl; - out << indent() << "}" << endl; + out << indent() << "if err := iprot.ReadMapEnd(ctx); err != nil {" << '\n'; + indent_up(); + out << indent() << "return thrift.PrependError(\"error reading map end: \", err)" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; } else if (ttype->is_set()) { - out << indent() << "if err := iprot.ReadSetEnd(ctx); err != nil {" << endl; - out << indent() << " return thrift.PrependError(\"error reading set end: \", err)" << endl; - out << indent() << "}" << endl; + out << indent() << "if err := iprot.ReadSetEnd(ctx); err != nil {" << '\n'; + indent_up(); + out << indent() << "return thrift.PrependError(\"error reading set end: \", err)" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; } else if (ttype->is_list()) { - out << indent() << "if err := iprot.ReadListEnd(ctx); err != nil {" << endl; - out << indent() << " return thrift.PrependError(\"error reading list end: \", err)" << endl; - out << indent() << "}" << endl; + out << indent() << "if err := iprot.ReadListEnd(ctx); err != nil {" << '\n'; + indent_up(); + out << indent() << "return thrift.PrependError(\"error reading list end: \", err)" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; } } @@ -3292,7 +3541,7 @@ void t_go_generator::generate_deserialize_map_element(ostream& out, fval.set_req(t_field::T_OPT_IN_REQ_OUT); generate_deserialize_field(out, &fkey, true, "", false, false, true); generate_deserialize_field(out, &fval, true, "", false, false, false, true); - indent(out) << prefix << "[" << key << "] = " << val << endl; + indent(out) << prefix << "[" << key << "] = " << val << '\n'; } /** @@ -3307,7 +3556,7 @@ void t_go_generator::generate_deserialize_set_element(ostream& out, t_field felem(tset->get_elem_type(), elem); felem.set_req(t_field::T_OPT_IN_REQ_OUT); generate_deserialize_field(out, &felem, true, "", false, false, false, true); - indent(out) << prefix << " = append(" << prefix << ", " << elem << ")" << endl; + indent(out) << prefix << " = append(" << prefix << ", " << elem << ")" << '\n'; } /** @@ -3322,7 +3571,7 @@ void t_go_generator::generate_deserialize_list_element(ostream& out, t_field felem(((t_list*)tlist)->get_elem_type(), elem); felem.set_req(t_field::T_OPT_IN_REQ_OUT); generate_deserialize_field(out, &felem, true, "", false, false, false, true); - indent(out) << prefix << " = append(" << prefix << ", " << elem << ")" << endl; + indent(out) << prefix << " = append(" << prefix << ", " << elem << ")" << '\n'; } /** @@ -3406,10 +3655,13 @@ void t_go_generator::generate_serialize_field(ostream& out, out << "WriteI32(ctx, int32(" << name << "))"; } - out << "; err != nil {" << endl; + out << "; err != nil {" << '\n'; + indent_up(); out << indent() << "return thrift.PrependError(fmt.Sprintf(\"%T." << escape_string(tfield->get_name()) << " (" << tfield->get_key() - << ") field write error: \", p), err) }" << endl; + << ") field write error: \", p), err)" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; } else { throw "compiler error: Invalid type in generate_serialize_field '" + type->get_name() + "' for field '" + name + "'"; @@ -3424,10 +3676,12 @@ void t_go_generator::generate_serialize_field(ostream& out, */ void t_go_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix) { (void)tstruct; - out << indent() << "if err := " << prefix << "." << write_method_name_ << "(ctx, oprot); err != nil {" << endl; - out << indent() << " return thrift.PrependError(fmt.Sprintf(\"%T error writing struct: \", " - << prefix << "), err)" << endl; - out << indent() << "}" << endl; + out << indent() << "if err := " << prefix << "." << write_method_name_ << "(ctx, oprot); err != nil {" << '\n'; + indent_up(); + out << indent() << "return thrift.PrependError(fmt.Sprintf(\"%T error writing struct: \", " + << prefix << "), err)" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; } void t_go_generator::generate_serialize_container(ostream& out, @@ -3441,21 +3695,27 @@ void t_go_generator::generate_serialize_container(ostream& out, out << indent() << "if err := oprot.WriteMapBegin(ctx, " << type_to_enum(((t_map*)ttype)->get_key_type()) << ", " << type_to_enum(((t_map*)ttype)->get_val_type()) << ", " - << "len(" << prefix << ")); err != nil {" << endl; - out << indent() << " return thrift.PrependError(\"error writing map begin: \", err)" << endl; - out << indent() << "}" << endl; + << "len(" << prefix << ")); err != nil {" << '\n'; + indent_up(); + out << indent() << "return thrift.PrependError(\"error writing map begin: \", err)" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; } else if (ttype->is_set()) { out << indent() << "if err := oprot.WriteSetBegin(ctx, " << type_to_enum(((t_set*)ttype)->get_elem_type()) << ", " - << "len(" << prefix << ")); err != nil {" << endl; - out << indent() << " return thrift.PrependError(\"error writing set begin: \", err)" << endl; - out << indent() << "}" << endl; + << "len(" << prefix << ")); err != nil {" << '\n'; + indent_up(); + out << indent() << "return thrift.PrependError(\"error writing set begin: \", err)" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; } else if (ttype->is_list()) { out << indent() << "if err := oprot.WriteListBegin(ctx, " << type_to_enum(((t_list*)ttype)->get_elem_type()) << ", " - << "len(" << prefix << ")); err != nil {" << endl; - out << indent() << " return thrift.PrependError(\"error writing list begin: \", err)" << endl; - out << indent() << "}" << endl; + << "len(" << prefix << ")); err != nil {" << '\n'; + indent_up(); + out << indent() << "return thrift.PrependError(\"error writing list begin: \", err)" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; } else { throw "compiler error: Invalid type in generate_serialize_container '" + ttype->get_name() + "' for prefix '" + prefix + "'"; @@ -3463,66 +3723,71 @@ void t_go_generator::generate_serialize_container(ostream& out, if (ttype->is_map()) { t_map* tmap = (t_map*)ttype; - out << indent() << "for k, v := range " << prefix << " {" << endl; + out << indent() << "for k, v := range " << prefix << " {" << '\n'; indent_up(); generate_serialize_map_element(out, tmap, "k", "v"); indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } else if (ttype->is_set()) { t_set* tset = (t_set*)ttype; - out << indent() << "for i := 0; iget_elem_type()); - out << indent() << "if func(tgt, src " << goType << ") bool {" << endl; + out << indent() << "if func(tgt, src " << goType << ") bool {" << '\n'; indent_up(); generate_go_equals(out, tset->get_elem_type(), "tgt", "src"); - out << indent() << "return true" << endl; + out << indent() << "return true" << '\n'; indent_down(); - out << indent() << "}(" << wrapped_prefix << "[i], " << wrapped_prefix << "[j]) {" << endl; + out << indent() << "}(" << wrapped_prefix << "[i], " << wrapped_prefix << "[j]) {" << '\n'; indent_up(); - out << indent() - << "return thrift.PrependError(\"\", fmt.Errorf(\"%T error writing set field: slice is not " - "unique\", " - << wrapped_prefix << "))" << endl; + out << indent() << "return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, " + << "fmt.Errorf(\"%T error writing set field: slice is not " "unique\", " + << wrapped_prefix << "))" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; indent_down(); - out << indent() << "}" << endl; - out << indent() << "for _, v := range " << prefix << " {" << endl; + out << indent() << "}" << '\n'; + out << indent() << "for _, v := range " << prefix << " {" << '\n'; indent_up(); generate_serialize_set_element(out, tset, "v"); indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } else if (ttype->is_list()) { t_list* tlist = (t_list*)ttype; - out << indent() << "for _, v := range " << prefix << " {" << endl; + out << indent() << "for _, v := range " << prefix << " {" << '\n'; indent_up(); generate_serialize_list_element(out, tlist, "v"); indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } if (ttype->is_map()) { - out << indent() << "if err := oprot.WriteMapEnd(ctx); err != nil {" << endl; - out << indent() << " return thrift.PrependError(\"error writing map end: \", err)" << endl; - out << indent() << "}" << endl; + out << indent() << "if err := oprot.WriteMapEnd(ctx); err != nil {" << '\n'; + indent_up(); + out << indent() << "return thrift.PrependError(\"error writing map end: \", err)" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; } else if (ttype->is_set()) { - out << indent() << "if err := oprot.WriteSetEnd(ctx); err != nil {" << endl; - out << indent() << " return thrift.PrependError(\"error writing set end: \", err)" << endl; - out << indent() << "}" << endl; + out << indent() << "if err := oprot.WriteSetEnd(ctx); err != nil {" << '\n'; + indent_up(); + out << indent() << "return thrift.PrependError(\"error writing set end: \", err)" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; } else if (ttype->is_list()) { - out << indent() << "if err := oprot.WriteListEnd(ctx); err != nil {" << endl; - out << indent() << " return thrift.PrependError(\"error writing list end: \", err)" << endl; - out << indent() << "}" << endl; + out << indent() << "if err := oprot.WriteListEnd(ctx); err != nil {" << '\n'; + indent_up(); + out << indent() << "return thrift.PrependError(\"error writing list end: \", err)" << '\n'; + indent_down(); + out << indent() << "}" << '\n'; } } @@ -3609,7 +3874,7 @@ void t_go_generator::generate_go_equals(ostream& out, t_type* ori_type, string t out << tgt << " != " << src; } - out << " { return false }" << endl; + out << " { return false }" << '\n'; } else { throw "compiler error: Invalid type in generate_go_equals '" + ttype->get_name() + "' for '" + tgt + "'"; @@ -3625,7 +3890,7 @@ void t_go_generator::generate_go_equals_struct(ostream& out, string src) { (void)ttype; out << indent() << "if !" << tgt << "." << equals_method_name_ << "(" << src - << ") { return false }" << endl; + << ") { return false }" << '\n'; } /** @@ -3635,16 +3900,16 @@ void t_go_generator::generate_go_equals_container(ostream& out, t_type* ttype, string tgt, string src) { - out << indent() << "if len(" << tgt << ") != len(" << src << ") { return false }" << endl; + out << indent() << "if len(" << tgt << ") != len(" << src << ") { return false }" << '\n'; if (ttype->is_map()) { t_map* tmap = (t_map*)ttype; - out << indent() << "for k, _tgt := range " << tgt << " {" << endl; + out << indent() << "for k, _tgt := range " << tgt << " {" << '\n'; indent_up(); string element_source = tmp("_src"); - out << indent() << element_source << " := " << src << "[k]" << endl; + out << indent() << element_source << " := " << src << "[k]" << '\n'; generate_go_equals(out, tmap->get_val_type(), "_tgt", element_source); indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } else if (ttype->is_list() || ttype->is_set()) { t_type* elem; if (ttype->is_list()) { @@ -3654,13 +3919,13 @@ void t_go_generator::generate_go_equals_container(ostream& out, t_set* temp = (t_set*)ttype; elem = temp->get_elem_type(); } - out << indent() << "for i, _tgt := range " << tgt << " {" << endl; + out << indent() << "for i, _tgt := range " << tgt << " {" << '\n'; indent_up(); string element_source = tmp("_src"); - out << indent() << element_source << " := " << src << "[i]" << endl; + out << indent() << element_source << " := " << src << "[i]" << '\n'; generate_go_equals(out, elem, "_tgt", element_source); indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } else { throw "INVALID TYPE IN generate_go_equals_container '" + ttype->get_name(); } @@ -3699,7 +3964,7 @@ void t_go_generator::generate_go_docstring(ostream& out, if (fields.size() > 0) { if (has_doc) { - ss << endl; + ss << '\n'; } has_doc = true; @@ -3713,9 +3978,10 @@ void t_go_generator::generate_go_docstring(ostream& out, if (p->has_doc()) { ss << ": " << p->get_doc(); } else { - ss << endl; + ss << '\n'; } } + ss << '\n'; } if (has_doc) { @@ -4097,6 +4363,32 @@ void t_go_generator::parse_go_tags(map* tags, const string in) { } } +void t_go_generator::generate_deprecation_comment(ostream& out, const map>& annotations) { + auto iter = annotations.find("deprecated"); + if (annotations.end() != iter) { + out << indent() << "// Deprecated: "; + + bool first = true; + for (auto str_iter = iter->second.begin(); str_iter != iter->second.end(); ++str_iter) { + if (*str_iter == "1") { + // Empty annotations will generate "1", skip those. + continue; + } + if (first) { + first = false; + } else { + out << "; "; + } + out << *str_iter; + } + if (first) { + // All deprecation annotations are empty, put a generic reason here + out << "(no reason given)"; + } + out << '\n'; + } +} + bool format_go_output(const string& file_path) { // formatting via gofmt deactivated due to THRIFT-3893 diff --git a/compiler/cpp/src/thrift/generate/t_go_generator.h b/compiler/cpp/src/thrift/generate/t_go_generator.h index a67485c5506..72825bc9caa 100644 --- a/compiler/cpp/src/thrift/generate/t_go_generator.h +++ b/compiler/cpp/src/thrift/generate/t_go_generator.h @@ -44,8 +44,6 @@ using std::string; using std::stringstream; using std::vector; -static const string endl = "\n"; // avoid ostream << std::endl flushes - const string DEFAULT_THRIFT_IMPORT = "github.com/apache/thrift/lib/go/thrift"; static std::string package_flag; @@ -268,6 +266,8 @@ class t_go_generator : public t_generator { std::string type_to_go_key_type(t_type* ttype); std::string type_to_spec_args(t_type* ttype); + void generate_deprecation_comment(std::ostream& os, const std::map>& annotations); + void indent_up() { t_generator::indent_up(); } void indent_down() { t_generator::indent_down(); } std::string indent() { return t_generator::indent(); } @@ -288,6 +288,10 @@ class t_go_generator : public t_generator { static bool is_pointer_field(t_field* tfield, bool in_container = false); + std::string indent_str() const override { + return "\t"; + } + private: std::string gen_package_prefix_; std::string gen_thrift_import_; diff --git a/compiler/cpp/src/thrift/generate/t_gv_generator.cc b/compiler/cpp/src/thrift/generate/t_gv_generator.cc index f8616ffb345..c91200b4916 100644 --- a/compiler/cpp/src/thrift/generate/t_gv_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_gv_generator.cc @@ -38,8 +38,6 @@ using std::string; using std::stringstream; using std::vector; -static const string endl = "\n"; // avoid ostream << std::endl flushes - /** * Graphviz code generator */ @@ -110,10 +108,10 @@ void t_gv_generator::init_generator() { MKDIR(get_out_dir().c_str()); string fname = get_out_dir() + program_->get_name() + ".gv"; f_out_.open(fname.c_str()); - f_out_ << "digraph \"" << escape_string(program_name_) << "\" {" << endl; - f_out_ << "node [style=filled, shape=record];" << endl; - f_out_ << "edge [arrowsize=0.5];" << endl; - f_out_ << "rankdir=LR" << endl; + f_out_ << "digraph \"" << escape_string(program_name_) << "\" {" << '\n'; + f_out_ << "node [style=filled, shape=record];" << '\n'; + f_out_ << "edge [arrowsize=0.5];" << '\n'; + f_out_ << "rankdir=LR" << '\n'; } /** @@ -126,29 +124,29 @@ void t_gv_generator::close_generator() { // Print edges std::list::iterator iter = edges.begin(); for (; iter != edges.end(); iter++) { - f_out_ << (*iter) << endl; + f_out_ << (*iter) << '\n'; } // Print graph end } and close file - f_out_ << "}" << endl; + f_out_ << "}" << '\n'; f_out_.close(); } void t_gv_generator::generate_typedef(t_typedef* ttypedef) { string name = ttypedef->get_name(); - f_out_ << "node [fillcolor=azure];" << endl; + f_out_ << "node [fillcolor=azure];" << '\n'; f_out_ << name << " [label=\""; f_out_ << escape_string(name); f_out_ << " :: "; print_type(ttypedef->get_type(), name); - f_out_ << "\"];" << endl; + f_out_ << "\"];" << '\n'; } void t_gv_generator::generate_enum(t_enum* tenum) { string name = tenum->get_name(); - f_out_ << "node [fillcolor=white];" << endl; + f_out_ << "node [fillcolor=white];" << '\n'; f_out_ << name << " [label=\"enum " << escape_string(name); vector values = tenum->get_constants(); @@ -159,13 +157,13 @@ void t_gv_generator::generate_enum(t_enum* tenum) { f_out_ << (*val_iter)->get_value(); } - f_out_ << "\"];" << endl; + f_out_ << "\"];" << '\n'; } void t_gv_generator::generate_const(t_const* tconst) { string name = tconst->get_name(); - f_out_ << "node [fillcolor=aliceblue];" << endl; + f_out_ << "node [fillcolor=aliceblue];" << '\n'; f_out_ << "const_" << name << " [label=\""; f_out_ << escape_string(name); @@ -174,22 +172,22 @@ void t_gv_generator::generate_const(t_const* tconst) { f_out_ << " :: "; print_type(tconst->get_type(), "const_" + name); - f_out_ << "\"];" << endl; + f_out_ << "\"];" << '\n'; } void t_gv_generator::generate_struct(t_struct* tstruct) { string name = tstruct->get_name(); if (tstruct->is_xception()) { - f_out_ << "node [fillcolor=lightpink];" << endl; + f_out_ << "node [fillcolor=lightpink];" << '\n'; f_out_ << name << " [label=\""; f_out_ << "exception " << escape_string(name); } else if (tstruct->is_union()) { - f_out_ << "node [fillcolor=lightcyan];" << endl; + f_out_ << "node [fillcolor=lightcyan];" << '\n'; f_out_ << name << " [label=\""; f_out_ << "union " << escape_string(name); } else { - f_out_ << "node [fillcolor=beige];" << endl; + f_out_ << "node [fillcolor=beige];" << '\n'; f_out_ << name << " [label=\""; f_out_ << "struct " << escape_string(name); } @@ -208,7 +206,7 @@ void t_gv_generator::generate_struct(t_struct* tstruct) { print_type((*mem_iter)->get_type(), name + ":field_" + field_name); } - f_out_ << "\"];" << endl; + f_out_ << "\"];" << '\n'; } void t_gv_generator::print_type(t_type* ttype, string struct_field_ref) { @@ -296,10 +294,10 @@ void t_gv_generator::print_const_value(t_type* type, t_const_value* tvalue) { void t_gv_generator::generate_service(t_service* tservice) { string service_name = get_service_name(tservice); - f_out_ << "subgraph cluster_" << service_name << " {" << endl; - f_out_ << "node [fillcolor=bisque];" << endl; - f_out_ << "style=dashed;" << endl; - f_out_ << "label = \"" << escape_string(service_name) << " service\";" << endl; + f_out_ << "subgraph cluster_" << service_name << " {" << '\n'; + f_out_ << "node [fillcolor=bisque];" << '\n'; + f_out_ << "style=dashed;" << '\n'; + f_out_ << "label = \"" << escape_string(service_name) << " service\";" << '\n'; // TODO: service extends @@ -327,7 +325,7 @@ void t_gv_generator::generate_service(t_service* tservice) { "function_" + service_name + fn_name + ":param_" + (*arg_iter)->get_name()); } // end of node - f_out_ << "\"];" << endl; + f_out_ << "\"];" << '\n'; // Exception edges if (exception_arrows) { @@ -340,7 +338,7 @@ void t_gv_generator::generate_service(t_service* tservice) { } } - f_out_ << " }" << endl; + f_out_ << " }" << '\n'; } std::string t_gv_generator::display_name() const { diff --git a/compiler/cpp/src/thrift/generate/t_haxe_generator.cc b/compiler/cpp/src/thrift/generate/t_haxe_generator.cc index b236e0bc619..94f7f541d72 100644 --- a/compiler/cpp/src/thrift/generate/t_haxe_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_haxe_generator.cc @@ -37,8 +37,6 @@ using std::string; using std::stringstream; using std::vector; -static const string endl = "\n"; // avoid ostream << std::endl flushes - /** * Haxe code generator. * @@ -99,16 +97,16 @@ class t_haxe_generator : public t_oop_generator { t_const_value* value); void render_struct_initializer(std::ostream& out, - t_struct* type, + t_struct* type, t_const_value* value); void render_map_initializer(std::ostream& out, - t_map* type, + t_map* type, t_const_value* value); void render_list_initializer(std::ostream& out, - t_list* type, + t_list* type, t_const_value* value); void render_set_initializer(std::ostream& out, - t_set* type, + t_set* type, t_const_value* value); // helper @@ -424,10 +422,10 @@ void t_haxe_generator::generate_enum(t_enum* tenum) { f_enum.open(f_enum_name.c_str()); // Comment and package it - f_enum << autogen_comment() << haxe_package() << ";" << endl << endl; + f_enum << autogen_comment() << haxe_package() << ";" << '\n' << '\n'; // Add haxe imports - f_enum << string() + "import org.apache.thrift.helper.*;" << endl << endl; + f_enum << string() + "import org.apache.thrift.helper.*;" << '\n' << '\n'; generate_rtti_decoration(f_enum); generate_macro_decoration(f_enum); @@ -439,11 +437,11 @@ void t_haxe_generator::generate_enum(t_enum* tenum) { for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) { int value = (*c_iter)->get_value(); indent(f_enum) << "public static inline var " << (*c_iter)->get_name() << " : Int = " << value - << ";" << endl; + << ";" << '\n'; } // Create a static Set with all valid values for this enum - f_enum << endl; + f_enum << '\n'; indent(f_enum) << "public static var VALID_VALUES = { new IntSet( ["; indent_up(); @@ -454,19 +452,19 @@ void t_haxe_generator::generate_enum(t_enum* tenum) { firstValue = false; } indent_down(); - f_enum << "]); };" << endl; + f_enum << "]); };" << '\n'; indent(f_enum) << "public static var VALUES_TO_NAMES = { ["; indent_up(); firstValue = true; for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) { - f_enum << (firstValue ? "" : ",") << endl; + f_enum << (firstValue ? "" : ",") << '\n'; indent(f_enum) << (*c_iter)->get_name() << " => \"" << (*c_iter)->get_name() << "\""; firstValue = false; } - f_enum << endl; + f_enum << '\n'; indent_down(); - indent(f_enum) << "]; };" << endl; + indent(f_enum) << "]; };" << '\n'; scope_down(f_enum); // end class @@ -486,15 +484,15 @@ void t_haxe_generator::generate_consts(std::vector consts) { f_consts.open(f_consts_name.c_str()); // Print header - f_consts << autogen_comment() << haxe_package() << ";" << endl << endl; + f_consts << autogen_comment() << haxe_package() << ";" << '\n' << '\n'; - f_consts << endl; + f_consts << '\n'; f_consts << haxe_type_imports(); generate_rtti_decoration(f_consts); generate_macro_decoration(f_consts); - indent(f_consts) << "class " << get_cap_name(program_name_) << "Constants {" << endl << endl; + indent(f_consts) << "class " << get_cap_name(program_name_) << "Constants {" << '\n' << '\n'; indent_up(); vector::iterator c_iter; for (c_iter = consts.begin(); c_iter != consts.end(); ++c_iter) { @@ -504,7 +502,7 @@ void t_haxe_generator::generate_consts(std::vector consts) { (*c_iter)->get_value()); } indent_down(); - indent(f_consts) << "}" << endl; + indent(f_consts) << "}" << '\n'; f_consts.close(); } @@ -527,7 +525,7 @@ void t_haxe_generator::print_const_value(std::ostream& out, } out << " : " << get_cap_name(type_name(type)) << " = "; render_const_value(out, type, value); - out << ";" << endl << endl; + out << ";" << '\n' << '\n'; } std::string t_haxe_generator::render_const_value_str( t_type* type, t_const_value* value) { @@ -594,9 +592,9 @@ void t_haxe_generator::render_const_value(std::ostream& out, void t_haxe_generator::render_struct_initializer(std::ostream& out, t_struct* type, t_const_value* value) { - out << "(function() : " << get_cap_name(type_name(type)) << " {" << endl; + out << "(function() : " << get_cap_name(type_name(type)) << " {" << '\n'; indent_up(); - indent(out) << "var tmp = new " << get_cap_name(type_name(type)) << "();" << endl; + indent(out) << "var tmp = new " << get_cap_name(type_name(type)) << "();" << '\n'; const vector& fields = ((t_struct*)type)->get_members(); vector::const_iterator f_iter; @@ -615,24 +613,24 @@ void t_haxe_generator::render_struct_initializer(std::ostream& out, } indent(out) << "tmp." << v_iter->first->get_string() << " = "; render_const_value(out, field_type, v_iter->second); - out << ";" << endl; + out << ";" << '\n'; } - indent(out) << "return tmp;" << endl; + indent(out) << "return tmp;" << '\n'; indent_down(); - indent(out) << "})()"; // no endl + indent(out) << "})()"; // no line break } void t_haxe_generator::render_map_initializer(std::ostream& out, t_map* type, t_const_value* value) { - out << "(function() : " << get_cap_name(type_name(type)) << " {" << endl; + out << "(function() : " << get_cap_name(type_name(type)) << " {" << '\n'; indent_up(); - indent(out) << "var tmp = new " << get_cap_name(type_name(type)) << "();" << endl; + indent(out) << "var tmp = new " << get_cap_name(type_name(type)) << "();" << '\n'; t_type* key_type = ((t_map*)type)->get_key_type(); t_type* val_type = ((t_map*)type)->get_val_type(); - + const map& values = value->get_map(); map::const_iterator v_iter; for (v_iter = values.begin(); v_iter != values.end(); ++v_iter) { @@ -640,56 +638,56 @@ void t_haxe_generator::render_map_initializer(std::ostream& out, render_const_value(out, key_type, v_iter->first); out << ", "; render_const_value(out, val_type, v_iter->second); - out << ");" << endl; + out << ");" << '\n'; } - - indent(out) << "return tmp;" << endl; + + indent(out) << "return tmp;" << '\n'; indent_down(); - indent(out) << "})()"; // no endl + indent(out) << "})()"; // no line break } void t_haxe_generator::render_list_initializer(std::ostream& out, t_list* type, t_const_value* value) { - out << "(function() : " << get_cap_name(type_name(type)) << " {" << endl; + out << "(function() : " << get_cap_name(type_name(type)) << " {" << '\n'; indent_up(); - indent(out) << "var tmp = new " << get_cap_name(type_name(type)) << "();" << endl; + indent(out) << "var tmp = new " << get_cap_name(type_name(type)) << "();" << '\n'; t_type* elm_type = type->get_elem_type(); - + const vector& values = value->get_list(); vector::const_iterator v_iter; for (v_iter = values.begin(); v_iter != values.end(); ++v_iter) { indent(out) << "tmp.add("; render_const_value(out, elm_type, *v_iter); - out << ");" << endl; + out << ");" << '\n'; } - - indent(out) << "return tmp;" << endl; + + indent(out) << "return tmp;" << '\n'; indent_down(); - indent(out) << "})()"; // no endl + indent(out) << "})()"; // no line break } void t_haxe_generator::render_set_initializer(std::ostream& out, t_set* type, t_const_value* value) { - out << "(function() : " << get_cap_name(type_name(type)) << " {" << endl; + out << "(function() : " << get_cap_name(type_name(type)) << " {" << '\n'; indent_up(); - indent(out) << "var tmp = new " << get_cap_name(type_name(type)) << "();" << endl; + indent(out) << "var tmp = new " << get_cap_name(type_name(type)) << "();" << '\n'; t_type* elm_type = type->get_elem_type(); - + const vector& values = value->get_list(); vector::const_iterator v_iter; for (v_iter = values.begin(); v_iter != values.end(); ++v_iter) { indent(out) << "tmp.add("; render_const_value(out, elm_type, *v_iter); - out << ");" << endl; + out << ");" << '\n'; } - - indent(out) << "return tmp;" << endl; + + indent(out) << "return tmp;" << '\n'; indent_down(); - indent(out) << "})()"; // no endl + indent(out) << "})()"; // no line break } @@ -723,14 +721,14 @@ void t_haxe_generator::generate_haxe_struct(t_struct* tstruct, bool is_exception ofstream_with_content_based_conditional_update f_struct; f_struct.open(f_struct_name.c_str()); - f_struct << autogen_comment() << haxe_package() << ";" << endl; + f_struct << autogen_comment() << haxe_package() << ";" << '\n'; - f_struct << endl; + f_struct << '\n'; string imports; f_struct << haxe_type_imports() << haxe_thrift_imports() - << haxe_thrift_gen_imports(tstruct, imports) << endl; + << haxe_thrift_gen_imports(tstruct, imports) << '\n'; generate_haxe_struct_definition(f_struct, tstruct, is_exception, is_result); @@ -762,11 +760,11 @@ void t_haxe_generator::generate_haxe_struct_definition(ostream& out, if (is_exception) { out << "extends TException "; } - out << "implements TBase {" << endl << endl; + out << "implements TBase {" << '\n' << '\n'; indent_up(); indent(out) << "static var STRUCT_DESC = { new TStruct(\"" << tstruct->get_name() << "\"); };" - << endl; + << '\n'; const vector& members = tstruct->get_members(); vector::const_iterator m_iter; @@ -775,69 +773,69 @@ void t_haxe_generator::generate_haxe_struct_definition(ostream& out, indent(out) << "static var " << constant_name((*m_iter)->get_name()) << "_FIELD_DESC = { new TField(\"" << (*m_iter)->get_name() << "\", " << type_to_enum((*m_iter)->get_type()) << ", " << (*m_iter)->get_key() << "); };" - << endl; + << '\n'; } - out << endl; + out << '\n'; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { generate_haxe_doc(out, *m_iter); // indent(out) << "private var _" << (*m_iter)->get_name() + " : " + - // type_name((*m_iter)->get_type()) << ";" << endl; - indent(out) << "@:isVar" << endl; + // type_name((*m_iter)->get_type()) << ";" << '\n'; + indent(out) << "@:isVar" << '\n'; indent(out) << "public var " << (*m_iter)->get_name() + "(get,set) : " - + get_cap_name(type_name((*m_iter)->get_type())) << ";" << endl; + + get_cap_name(type_name((*m_iter)->get_type())) << ";" << '\n'; } - out << endl; + out << '\n'; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { indent(out) << "inline static var " << upcase_string((*m_iter)->get_name()) - << "_FIELD_ID : Int = " << (*m_iter)->get_key() << ";" << endl; + << "_FIELD_ID : Int = " << (*m_iter)->get_key() << ";" << '\n'; } - out << endl; + out << '\n'; // Inner Isset class if (members.size() > 0) { for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { if (!type_can_be_null((*m_iter)->get_type())) { indent(out) << "private var __isset_" << (*m_iter)->get_name() << " : Bool = false;" - << endl; + << '\n'; } } } - out << endl; + out << '\n'; // Static initializer to populate global class to struct metadata map if (false) { // TODO: reactivate when needed generate_haxe_meta_data_map(out, tstruct); - indent(out) << "{" << endl; + indent(out) << "{" << '\n'; indent_up(); indent(out) << "FieldMetaData.addStructMetaDataMap(" << type_name(tstruct) << ", metaDataMap);" - << endl; + << '\n'; indent_down(); - indent(out) << "}" << endl; - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; + indent(out) << "}" << '\n'; } // Default constructor - indent(out) << "public function new() {" << endl; + indent(out) << "public function new() {" << '\n'; indent_up(); if (is_exception) { - indent(out) << "super();" << endl; + indent(out) << "super();" << '\n'; } for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { if ((*m_iter)->get_value() != nullptr) { indent(out) << "this." << (*m_iter)->get_name() << " = "; render_const_value( out, (*m_iter)->get_type(), (*m_iter)->get_value()); - out << ";" << endl; + out << ";" << '\n'; } } indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; generate_property_getters_setters(out, tstruct); generate_generic_field_getters_setters(out, tstruct); @@ -852,7 +850,7 @@ void t_haxe_generator::generate_haxe_struct_definition(ostream& out, generate_haxe_struct_tostring(out, tstruct, is_exception); generate_haxe_validator(out, tstruct); scope_down(out); - out << endl; + out << '\n'; } /** @@ -861,123 +859,123 @@ void t_haxe_generator::generate_haxe_struct_definition(ostream& out, * @param tstruct The struct definition */ void t_haxe_generator::generate_haxe_struct_reader(ostream& out, t_struct* tstruct) { - out << indent() << "public function read( iprot : TProtocol) : Void {" << endl; + out << indent() << "public function read( iprot : TProtocol) : Void {" << '\n'; indent_up(); const vector& fields = tstruct->get_members(); vector::const_iterator f_iter; - indent(out) << "iprot.IncrementRecursionDepth();" << endl; - indent(out) << "try" << endl; + indent(out) << "iprot.IncrementRecursionDepth();" << '\n'; + indent(out) << "try" << '\n'; scope_up(out); // Declare stack tmp variables and read struct header - out << indent() << "var field : TField;" << endl << indent() << "iprot.readStructBegin();" - << endl; + out << indent() << "var field : TField;" << '\n' << indent() << "iprot.readStructBegin();" + << '\n'; // Loop over reading in fields - indent(out) << "while (true)" << endl; + indent(out) << "while (true)" << '\n'; scope_up(out); // Read beginning field marker - indent(out) << "field = iprot.readFieldBegin();" << endl; + indent(out) << "field = iprot.readFieldBegin();" << '\n'; // Check for field STOP marker and break - indent(out) << "if (field.type == TType.STOP) { " << endl; + indent(out) << "if (field.type == TType.STOP) { " << '\n'; indent_up(); - indent(out) << "break;" << endl; + indent(out) << "break;" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; // Switch statement on the field we are reading - indent(out) << "switch (field.id)" << endl; + indent(out) << "switch (field.id)" << '\n'; scope_up(out); // Generate deserialization code for known cases for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { - indent(out) << "case " << upcase_string((*f_iter)->get_name()) << "_FIELD_ID:" << endl; + indent(out) << "case " << upcase_string((*f_iter)->get_name()) << "_FIELD_ID:" << '\n'; indent_up(); - indent(out) << "if (field.type == " << type_to_enum((*f_iter)->get_type()) << ") {" << endl; + indent(out) << "if (field.type == " << type_to_enum((*f_iter)->get_type()) << ") {" << '\n'; indent_up(); generate_deserialize_field(out, *f_iter, "this."); generate_isset_set(out, *f_iter); indent_down(); - out << indent() << "} else { " << endl << indent() << " TProtocolUtil.skip(iprot, field.type);" - << endl << indent() << "}" << endl; + out << indent() << "} else { " << '\n' << indent() << " TProtocolUtil.skip(iprot, field.type);" + << '\n' << indent() << "}" << '\n'; indent_down(); } // In the default case we skip the field - out << indent() << "default:" << endl << indent() << " TProtocolUtil.skip(iprot, field.type);" - << endl; + out << indent() << "default:" << '\n' << indent() << " TProtocolUtil.skip(iprot, field.type);" + << '\n'; scope_down(out); // Read field end marker - indent(out) << "iprot.readFieldEnd();" << endl; + indent(out) << "iprot.readFieldEnd();" << '\n'; scope_down(out); - out << indent() << "iprot.readStructEnd();" << endl << endl; + out << indent() << "iprot.readStructEnd();" << '\n' << '\n'; - indent(out) << "iprot.DecrementRecursionDepth();" << endl; + indent(out) << "iprot.DecrementRecursionDepth();" << '\n'; scope_down(out); - indent(out) << "catch(e:Dynamic)" << endl; + indent(out) << "catch(e:Dynamic)" << '\n'; scope_up(out); - indent(out) << "iprot.DecrementRecursionDepth();" << endl; - indent(out) << "throw e;" << endl; + indent(out) << "iprot.DecrementRecursionDepth();" << '\n'; + indent(out) << "throw e;" << '\n'; scope_down(out); // check for required fields of primitive type // (which can be checked here but not in the general validate method) - out << endl << indent() << "// check for required fields of primitive type, which can't be " - "checked in the validate method" << endl; + out << '\n' << indent() << "// check for required fields of primitive type, which can't be " + "checked in the validate method" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if ((*f_iter)->get_req() == t_field::T_REQUIRED && !type_can_be_null((*f_iter)->get_type())) { - out << indent() << "if (!__isset_" << (*f_iter)->get_name() << ") {" << endl << indent() + out << indent() << "if (!__isset_" << (*f_iter)->get_name() << ") {" << '\n' << indent() << " throw new TProtocolException(TProtocolException.UNKNOWN, \"Required field '" << (*f_iter)->get_name() - << "' was not found in serialized data! Struct: \" + toString());" << endl << indent() - << "}" << endl; + << "' was not found in serialized data! Struct: \" + toString());" << '\n' << indent() + << "}" << '\n'; } } // performs various checks (e.g. check that all required fields are set) - indent(out) << "validate();" << endl; + indent(out) << "validate();" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } // generates haxe method to perform various checks // (e.g. check that all required fields are set) void t_haxe_generator::generate_haxe_validator(ostream& out, t_struct* tstruct) { - indent(out) << "public function validate() : Void {" << endl; + indent(out) << "public function validate() : Void {" << '\n'; indent_up(); const vector& fields = tstruct->get_members(); vector::const_iterator f_iter; - out << indent() << "// check for required fields" << endl; + out << indent() << "// check for required fields" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if ((*f_iter)->get_req() == t_field::T_REQUIRED) { if (type_can_be_null((*f_iter)->get_type())) { - indent(out) << "if (" << (*f_iter)->get_name() << " == null) {" << endl; + indent(out) << "if (" << (*f_iter)->get_name() << " == null) {" << '\n'; indent(out) << " throw new TProtocolException(TProtocolException.UNKNOWN, \"Required field '" - << (*f_iter)->get_name() << "' was not present! Struct: \" + toString());" << endl; - indent(out) << "}" << endl; + << (*f_iter)->get_name() << "' was not present! Struct: \" + toString());" << '\n'; + indent(out) << "}" << '\n'; } else { indent(out) << "// alas, we cannot check '" << (*f_iter)->get_name() - << "' because it's a primitive." << endl; + << "' because it's a primitive." << '\n'; } } } // check that fields of type enum have valid values - out << indent() << "// check that fields of type enum have valid values" << endl; + out << indent() << "// check that fields of type enum have valid values" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { t_field* field = (*f_iter); t_type* type = field->get_type(); @@ -985,18 +983,18 @@ void t_haxe_generator::generate_haxe_validator(ostream& out, t_struct* tstruct) if (type->is_enum()) { indent(out) << "if (" << generate_isset_check(field) << " && !" << get_cap_name(get_enum_class_name(type)) << ".VALID_VALUES.contains(" - << field->get_name() << ")){" << endl; + << field->get_name() << ")){" << '\n'; indent_up(); indent(out) << "throw new TProtocolException(TProtocolException.UNKNOWN, \"The field '" << field->get_name() << "' has been assigned the invalid value \" + " - << field->get_name() << ");" << endl; + << field->get_name() << ");" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } } indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } /** @@ -1005,7 +1003,7 @@ void t_haxe_generator::generate_haxe_validator(ostream& out, t_struct* tstruct) * @param tstruct The struct definition */ void t_haxe_generator::generate_haxe_struct_writer(ostream& out, t_struct* tstruct) { - out << indent() << "public function write(oprot:TProtocol) : Void {" << endl; + out << indent() << "public function write(oprot:TProtocol) : Void {" << '\n'; indent_up(); string name = tstruct->get_name(); @@ -1013,57 +1011,57 @@ void t_haxe_generator::generate_haxe_struct_writer(ostream& out, t_struct* tstru vector::const_iterator f_iter; // performs various checks (e.g. check that all required fields are set) - indent(out) << "validate();" << endl; - indent(out) << "oprot.IncrementRecursionDepth();" << endl; - indent(out) << "try" << endl; + indent(out) << "validate();" << '\n'; + indent(out) << "oprot.IncrementRecursionDepth();" << '\n'; + indent(out) << "try" << '\n'; scope_up(out); - indent(out) << "oprot.writeStructBegin(STRUCT_DESC);" << endl; + indent(out) << "oprot.writeStructBegin(STRUCT_DESC);" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { bool could_be_unset = (*f_iter)->get_req() == t_field::T_OPTIONAL; if (could_be_unset) { - indent(out) << "if (" << generate_isset_check(*f_iter) << ") {" << endl; + indent(out) << "if (" << generate_isset_check(*f_iter) << ") {" << '\n'; indent_up(); } bool null_allowed = type_can_be_null((*f_iter)->get_type()); if (null_allowed) { - out << indent() << "if (this." << (*f_iter)->get_name() << " != null) {" << endl; + out << indent() << "if (this." << (*f_iter)->get_name() << " != null) {" << '\n'; indent_up(); } indent(out) << "oprot.writeFieldBegin(" << constant_name((*f_iter)->get_name()) - << "_FIELD_DESC);" << endl; + << "_FIELD_DESC);" << '\n'; // Write field contents generate_serialize_field(out, *f_iter, "this."); // Write field closer - indent(out) << "oprot.writeFieldEnd();" << endl; + indent(out) << "oprot.writeFieldEnd();" << '\n'; if (null_allowed) { indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } if (could_be_unset) { indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } } - indent(out) << "oprot.writeFieldStop();" << endl; - indent(out) << "oprot.writeStructEnd();" << endl; + indent(out) << "oprot.writeFieldStop();" << '\n'; + indent(out) << "oprot.writeStructEnd();" << '\n'; - indent(out) << "oprot.DecrementRecursionDepth();" << endl; + indent(out) << "oprot.DecrementRecursionDepth();" << '\n'; scope_down(out); - indent(out) << "catch(e:Dynamic)" << endl; + indent(out) << "catch(e:Dynamic)" << '\n'; scope_up(out); - indent(out) << "oprot.DecrementRecursionDepth();" << endl; - indent(out) << "throw e;" << endl; + indent(out) << "oprot.DecrementRecursionDepth();" << '\n'; + indent(out) << "throw e;" << '\n'; scope_down(out); indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } /** @@ -1075,59 +1073,59 @@ void t_haxe_generator::generate_haxe_struct_writer(ostream& out, t_struct* tstru * @param tstruct The struct definition */ void t_haxe_generator::generate_haxe_struct_result_writer(ostream& out, t_struct* tstruct) { - out << indent() << "public function write(oprot:TProtocol) : Void {" << endl; + out << indent() << "public function write(oprot:TProtocol) : Void {" << '\n'; indent_up(); string name = tstruct->get_name(); const vector& fields = tstruct->get_sorted_members(); vector::const_iterator f_iter; - indent(out) << "oprot.IncrementRecursionDepth();" << endl; - indent(out) << "try" << endl; + indent(out) << "oprot.IncrementRecursionDepth();" << '\n'; + indent(out) << "try" << '\n'; scope_up(out); - indent(out) << "oprot.writeStructBegin(STRUCT_DESC);" << endl; + indent(out) << "oprot.writeStructBegin(STRUCT_DESC);" << '\n'; bool first = true; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if (first) { first = false; - out << endl << indent() << "if "; + out << '\n' << indent() << "if "; } else { out << " else if "; } - out << "(this." << generate_isset_check(*f_iter) << ") {" << endl; + out << "(this." << generate_isset_check(*f_iter) << ") {" << '\n'; indent_up(); indent(out) << "oprot.writeFieldBegin(" << constant_name((*f_iter)->get_name()) - << "_FIELD_DESC);" << endl; + << "_FIELD_DESC);" << '\n'; // Write field contents generate_serialize_field(out, *f_iter, "this."); // Write field closer - indent(out) << "oprot.writeFieldEnd();" << endl; + indent(out) << "oprot.writeFieldEnd();" << '\n'; indent_down(); indent(out) << "}"; } - indent(out) << endl; - indent(out) << "oprot.writeFieldStop();" << endl; - indent(out) << "oprot.writeStructEnd();" << endl; + indent(out) << '\n'; + indent(out) << "oprot.writeFieldStop();" << '\n'; + indent(out) << "oprot.writeStructEnd();" << '\n'; - indent(out) << "oprot.DecrementRecursionDepth();" << endl; + indent(out) << "oprot.DecrementRecursionDepth();" << '\n'; scope_down(out); - indent(out) << "catch(e:Dynamic)" << endl; + indent(out) << "catch(e:Dynamic)" << '\n'; scope_up(out); - indent(out) << "oprot.DecrementRecursionDepth();" << endl; - indent(out) << "throw e;" << endl; + indent(out) << "oprot.DecrementRecursionDepth();" << '\n'; + indent(out) << "throw e;" << '\n'; scope_down(out); indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } void t_haxe_generator::generate_reflection_getters(ostringstream& out, @@ -1136,9 +1134,9 @@ void t_haxe_generator::generate_reflection_getters(ostringstream& out, string cap_name) { (void)type; (void)cap_name; - indent(out) << "case " << upcase_string(field_name) << "_FIELD_ID:" << endl; + indent(out) << "case " << upcase_string(field_name) << "_FIELD_ID:" << '\n'; indent_up(); - indent(out) << "return this." << field_name << ";" << endl; + indent(out) << "return this." << field_name << ";" << '\n'; indent_down(); } @@ -1148,13 +1146,13 @@ void t_haxe_generator::generate_reflection_setters(ostringstream& out, string cap_name) { (void)type; (void)cap_name; - indent(out) << "case " << upcase_string(field_name) << "_FIELD_ID:" << endl; + indent(out) << "case " << upcase_string(field_name) << "_FIELD_ID:" << '\n'; indent_up(); - indent(out) << "if (value == null) {" << endl; - indent(out) << " unset" << get_cap_name(field_name) << "();" << endl; - indent(out) << "} else {" << endl; - indent(out) << " this." << field_name << " = value;" << endl; - indent(out) << "}" << endl << endl; + indent(out) << "if (value == null) {" << '\n'; + indent(out) << " unset" << get_cap_name(field_name) << "();" << '\n'; + indent(out) << "} else {" << '\n'; + indent(out) << " this." << field_name << " = value;" << '\n'; + indent(out) << "}" << '\n' << '\n'; indent_down(); } @@ -1181,39 +1179,39 @@ void t_haxe_generator::generate_generic_field_getters_setters(std::ostream& out, } // create the setter - indent(out) << "public function setFieldValue(fieldID : Int, value : Dynamic) : Void {" << endl; + indent(out) << "public function setFieldValue(fieldID : Int, value : Dynamic) : Void {" << '\n'; indent_up(); if (fields.size() > 0) { - indent(out) << "switch (fieldID) {" << endl; + indent(out) << "switch (fieldID) {" << '\n'; out << setter_stream.str(); - indent(out) << "default:" << endl; - indent(out) << " throw new ArgumentError(\"Field \" + fieldID + \" doesn't exist!\");" << endl; - indent(out) << "}" << endl; + indent(out) << "default:" << '\n'; + indent(out) << " throw new ArgumentError(\"Field \" + fieldID + \" doesn't exist!\");" << '\n'; + indent(out) << "}" << '\n'; } else { - indent(out) << "throw new ArgumentError(\"Field \" + fieldID + \" doesn't exist!\");" << endl; + indent(out) << "throw new ArgumentError(\"Field \" + fieldID + \" doesn't exist!\");" << '\n'; } indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; // create the getter - indent(out) << "public function getFieldValue(fieldID : Int) : Dynamic {" << endl; + indent(out) << "public function getFieldValue(fieldID : Int) : Dynamic {" << '\n'; indent_up(); if (fields.size() > 0) { - indent(out) << "switch (fieldID) {" << endl; + indent(out) << "switch (fieldID) {" << '\n'; out << getter_stream.str(); - indent(out) << "default:" << endl; - indent(out) << " throw new ArgumentError(\"Field \" + fieldID + \" doesn't exist!\");" << endl; - indent(out) << "}" << endl; + indent(out) << "default:" << '\n'; + indent(out) << " throw new ArgumentError(\"Field \" + fieldID + \" doesn't exist!\");" << '\n'; + indent(out) << "}" << '\n'; } else { - indent(out) << "throw new ArgumentError(\"Field \" + fieldID + \" doesn't exist!\");" << endl; + indent(out) << "throw new ArgumentError(\"Field \" + fieldID + \" doesn't exist!\");" << '\n'; } indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } // Creates a generic isSet method that takes the field number as argument @@ -1223,29 +1221,29 @@ void t_haxe_generator::generate_generic_isset_method(std::ostream& out, t_struct // create the isSet method indent(out) << "// Returns true if field corresponding to fieldID is set (has been assigned a " - "value) and false otherwise" << endl; - indent(out) << "public function isSet(fieldID : Int) : Bool {" << endl; + "value) and false otherwise" << '\n'; + indent(out) << "public function isSet(fieldID : Int) : Bool {" << '\n'; indent_up(); if (fields.size() > 0) { - indent(out) << "switch (fieldID) {" << endl; + indent(out) << "switch (fieldID) {" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { t_field* field = *f_iter; - indent(out) << "case " << upcase_string(field->get_name()) << "_FIELD_ID:" << endl; + indent(out) << "case " << upcase_string(field->get_name()) << "_FIELD_ID:" << '\n'; indent_up(); - indent(out) << "return " << generate_isset_check(field) << ";" << endl; + indent(out) << "return " << generate_isset_check(field) << ";" << '\n'; indent_down(); } - indent(out) << "default:" << endl; - indent(out) << " throw new ArgumentError(\"Field \" + fieldID + \" doesn't exist!\");" << endl; - indent(out) << "}" << endl; + indent(out) << "default:" << '\n'; + indent(out) << " throw new ArgumentError(\"Field \" + fieldID + \" doesn't exist!\");" << '\n'; + indent(out) << "}" << '\n'; } else { - indent(out) << "throw new ArgumentError(\"Field \" + fieldID + \" doesn't exist!\");" << endl; + indent(out) << "throw new ArgumentError(\"Field \" + fieldID + \" doesn't exist!\");" << '\n'; } indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } /** @@ -1265,48 +1263,48 @@ void t_haxe_generator::generate_property_getters_setters(ostream& out, t_struct* // Simple getter generate_haxe_doc(out, field); indent(out) << "public function get_" << field_name << "() : " << get_cap_name(type_name(type)) - << " {" << endl; + << " {" << '\n'; indent_up(); - indent(out) << "return this." << field_name << ";" << endl; + indent(out) << "return this." << field_name << ";" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; // Simple setter generate_haxe_doc(out, field); indent(out) << "public function set_" << field_name << "(" << field_name << ":" << get_cap_name(type_name(type)) << ") : " << get_cap_name(type_name(type)) << " {" - << endl; + << '\n'; indent_up(); - indent(out) << "this." << field_name << " = " << field_name << ";" << endl; + indent(out) << "this." << field_name << " = " << field_name << ";" << '\n'; generate_isset_set(out, field); - indent(out) << "return this." << field_name << ";" << endl; + indent(out) << "return this." << field_name << ";" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; // Unsetter - indent(out) << "public function unset" << cap_name << "() : Void {" << endl; + indent(out) << "public function unset" << cap_name << "() : Void {" << '\n'; indent_up(); if (type_can_be_null(type)) { - indent(out) << "this." << field_name << " = null;" << endl; + indent(out) << "this." << field_name << " = null;" << '\n'; } else { - indent(out) << "this.__isset_" << field_name << " = false;" << endl; + indent(out) << "this.__isset_" << field_name << " = false;" << '\n'; } indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; // isSet method indent(out) << "// Returns true if field " << field_name - << " is set (has been assigned a value) and false otherwise" << endl; - indent(out) << "public function is" << get_cap_name("set") << cap_name << "() : Bool {" << endl; + << " is set (has been assigned a value) and false otherwise" << '\n'; + indent(out) << "public function is" << get_cap_name("set") << cap_name << "() : Bool {" << '\n'; indent_up(); if (type_can_be_null(type)) { - indent(out) << "return this." << field_name << " != null;" << endl; + indent(out) << "return this." << field_name << " != null;" << '\n'; } else { - indent(out) << "return this.__isset_" << field_name << ";" << endl; + indent(out) << "return this.__isset_" << field_name << ";" << '\n'; } indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } } @@ -1320,11 +1318,11 @@ void t_haxe_generator::generate_haxe_struct_tostring(ostream& out, t_struct* tst if( is_override) { out << "override "; } - out << "function toString() : String {" << endl; + out << "function toString() : String {" << '\n'; indent_up(); - out << indent() << "var ret : String = \"" << tstruct->get_name() << "(\";" << endl; - out << indent() << "var first : Bool = true;" << endl << endl; + out << indent() << "var ret : String = \"" << tstruct->get_name() << "(\";" << '\n'; + out << indent() << "var first : Bool = true;" << '\n' << '\n'; const vector& fields = tstruct->get_members(); vector::const_iterator f_iter; @@ -1332,58 +1330,58 @@ void t_haxe_generator::generate_haxe_struct_tostring(ostream& out, t_struct* tst for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { bool could_be_unset = (*f_iter)->get_req() == t_field::T_OPTIONAL; if (could_be_unset) { - indent(out) << "if (" << generate_isset_check(*f_iter) << ") {" << endl; + indent(out) << "if (" << generate_isset_check(*f_iter) << ") {" << '\n'; indent_up(); } t_field* field = (*f_iter); if (!first) { - indent(out) << "if (!first) ret += \", \";" << endl; + indent(out) << "if (!first) ret += \", \";" << '\n'; } - indent(out) << "ret += \"" << (*f_iter)->get_name() << ":\";" << endl; + indent(out) << "ret += \"" << (*f_iter)->get_name() << ":\";" << '\n'; bool can_be_null = type_can_be_null(field->get_type()); if (can_be_null) { - indent(out) << "if (this." << (*f_iter)->get_name() << " == null) {" << endl; - indent(out) << " ret += \"null\";" << endl; - indent(out) << "} else {" << endl; + indent(out) << "if (this." << (*f_iter)->get_name() << " == null) {" << '\n'; + indent(out) << " ret += \"null\";" << '\n'; + indent(out) << "} else {" << '\n'; indent_up(); } if (field->get_type()->is_binary()) { - indent(out) << " ret += \"BINARY\";" << endl; + indent(out) << " ret += \"BINARY\";" << '\n'; } else if (field->get_type()->is_enum()) { indent(out) << "var " << field->get_name() << "_name : String = " << get_cap_name(get_enum_class_name(field->get_type())) - << ".VALUES_TO_NAMES[this." << (*f_iter)->get_name() << "];" << endl; - indent(out) << "if (" << field->get_name() << "_name != null) {" << endl; - indent(out) << " ret += " << field->get_name() << "_name;" << endl; - indent(out) << " ret += \" (\";" << endl; - indent(out) << "}" << endl; - indent(out) << "ret += this." << field->get_name() << ";" << endl; - indent(out) << "if (" << field->get_name() << "_name != null) {" << endl; - indent(out) << " ret += \")\";" << endl; - indent(out) << "}" << endl; + << ".VALUES_TO_NAMES[this." << (*f_iter)->get_name() << "];" << '\n'; + indent(out) << "if (" << field->get_name() << "_name != null) {" << '\n'; + indent(out) << " ret += " << field->get_name() << "_name;" << '\n'; + indent(out) << " ret += \" (\";" << '\n'; + indent(out) << "}" << '\n'; + indent(out) << "ret += this." << field->get_name() << ";" << '\n'; + indent(out) << "if (" << field->get_name() << "_name != null) {" << '\n'; + indent(out) << " ret += \")\";" << '\n'; + indent(out) << "}" << '\n'; } else { - indent(out) << "ret += this." << (*f_iter)->get_name() << ";" << endl; + indent(out) << "ret += this." << (*f_iter)->get_name() << ";" << '\n'; } if (can_be_null) { indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } - indent(out) << "first = false;" << endl; + indent(out) << "first = false;" << '\n'; if (could_be_unset) { indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } first = false; } - out << indent() << "ret += \")\";" << endl << indent() << "return ret;" << endl; + out << indent() << "ret += \")\";" << '\n' << indent() << "return ret;" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } /** @@ -1397,7 +1395,7 @@ void t_haxe_generator::generate_haxe_meta_data_map(ostream& out, t_struct* tstru vector::const_iterator f_iter; // Static Map with fieldID -> FieldMetaData mappings - indent(out) << "inline static var metaDataMap : IntMap = new IntMap();" << endl; + indent(out) << "inline static var metaDataMap : IntMap = new IntMap();" << '\n'; if (fields.size() > 0) { // Populate map @@ -1419,7 +1417,7 @@ void t_haxe_generator::generate_haxe_meta_data_map(ostream& out, t_struct* tstru // Create value meta data generate_field_value_meta_data(out, field->get_type()); - out << ");" << endl; + out << ");" << '\n'; } scope_down(out); } @@ -1484,7 +1482,7 @@ std::string t_haxe_generator::get_haxe_type_string(t_type* type) { } void t_haxe_generator::generate_field_value_meta_data(std::ostream& out, t_type* type) { - out << endl; + out << '\n'; indent_up(); indent_up(); if (type->is_struct()) { @@ -1527,20 +1525,20 @@ void t_haxe_generator::generate_service(t_service* tservice) { string f_service_name = package_dir_ + "/" + get_cap_name(service_name_) + "_service.hx"; f_service_.open(f_service_name.c_str()); - f_service_ << autogen_comment() << haxe_package() << ";" << endl; + f_service_ << autogen_comment() << haxe_package() << ";" << '\n'; - f_service_ << endl << haxe_type_imports() << haxe_thrift_imports() + f_service_ << '\n' << haxe_type_imports() << haxe_thrift_imports() << haxe_thrift_gen_imports(tservice); if (tservice->get_extends() != nullptr) { t_type* parent = tservice->get_extends(); string parent_namespace = make_package_name( parent->get_program()->get_namespace("haxe")); if (!parent_namespace.empty() && parent_namespace != package_name_) { - f_service_ << "import " << get_cap_name(type_name(parent)) << "_service;" << endl; + f_service_ << "import " << get_cap_name(type_name(parent)) << "_service;" << '\n'; } } - f_service_ << endl; + f_service_ << '\n'; generate_service_interface(tservice,false); f_service_.close(); @@ -1549,20 +1547,20 @@ void t_haxe_generator::generate_service(t_service* tservice) { f_service_name = package_dir_ + "/" + get_cap_name(service_name_) + ".hx"; f_service_.open(f_service_name.c_str()); - f_service_ << autogen_comment() << haxe_package() << ";" << endl; + f_service_ << autogen_comment() << haxe_package() << ";" << '\n'; - f_service_ << endl << haxe_type_imports() << haxe_thrift_imports() + f_service_ << '\n' << haxe_type_imports() << haxe_thrift_imports() << haxe_thrift_gen_imports(tservice); if (tservice->get_extends() != nullptr) { t_type* parent = tservice->get_extends(); string parent_namespace = make_package_name( parent->get_program()->get_namespace("haxe")); if (!parent_namespace.empty() && parent_namespace != package_name_) { - f_service_ << "import " << get_cap_name(type_name(parent)) << ";" << endl; + f_service_ << "import " << get_cap_name(type_name(parent)) << ";" << '\n'; } } - f_service_ << endl; + f_service_ << '\n'; generate_service_interface(tservice,true); f_service_.close(); @@ -1571,18 +1569,18 @@ void t_haxe_generator::generate_service(t_service* tservice) { f_service_name = package_dir_ + "/" + get_cap_name(service_name_) + "Impl.hx"; f_service_.open(f_service_name.c_str()); - f_service_ << autogen_comment() << haxe_package() << ";" << endl << endl << haxe_type_imports() - << haxe_thrift_imports() << haxe_thrift_gen_imports(tservice) << endl; + f_service_ << autogen_comment() << haxe_package() << ";" << '\n' << '\n' << haxe_type_imports() + << haxe_thrift_imports() << haxe_thrift_gen_imports(tservice) << '\n'; if (tservice->get_extends() != nullptr) { t_type* parent = tservice->get_extends(); string parent_namespace = make_package_name( parent->get_program()->get_namespace("haxe")); if (!parent_namespace.empty() && parent_namespace != package_name_) { - f_service_ << "import " << get_cap_name(type_name(parent)) << "Impl;" << endl; + f_service_ << "import " << get_cap_name(type_name(parent)) << "Impl;" << '\n'; } } - f_service_ << endl; + f_service_ << '\n'; generate_service_client(tservice); f_service_.close(); @@ -1594,17 +1592,17 @@ void t_haxe_generator::generate_service(t_service* tservice) { f_service_name = package_dir_ + "/" + get_cap_name(service_name_) + "Processor.hx"; f_service_.open(f_service_name.c_str()); - f_service_ << autogen_comment() << haxe_package() << ";" << endl - << endl + f_service_ << autogen_comment() << haxe_package() << ";" << '\n' + << '\n' << haxe_type_imports() - << haxe_thrift_imports() - << haxe_thrift_gen_imports(tservice) - << endl; + << haxe_thrift_imports() + << haxe_thrift_gen_imports(tservice) + << '\n'; if (!package_name_.empty()) { - f_service_ << "import " << package_name_ << ".*;" << endl; - f_service_ << "import " << package_name_ << "." << get_cap_name(service_name_).c_str() << "Impl;" << endl; - f_service_ << endl; + f_service_ << "import " << package_name_ << ".*;" << '\n'; + f_service_ << "import " << package_name_ << "." << get_cap_name(service_name_).c_str() << "Impl;" << '\n'; + f_service_ << '\n'; } generate_service_server(tservice); @@ -1668,9 +1666,9 @@ void t_haxe_generator::generate_service_method_signature_normal(t_function* tfun bool is_interface) { if (is_interface) { generate_deprecation_attribute(f_service_, tfunction, true); - indent(f_service_) << function_signature_normal(tfunction) << ";" << endl << endl; + indent(f_service_) << function_signature_normal(tfunction) << ";" << '\n' << '\n'; } else { - indent(f_service_) << "public " << function_signature_normal(tfunction) << " {" << endl; + indent(f_service_) << "public " << function_signature_normal(tfunction) << " {" << '\n'; } } @@ -1683,15 +1681,15 @@ void t_haxe_generator::generate_service_method_signature_combined(t_function* tf bool is_interface) { if (!tfunction->is_oneway()) { std::string on_success_impl = generate_service_method_onsuccess(tfunction, false, false); - indent(f_service_) << "// function onError(Dynamic) : Void;" << endl; - indent(f_service_) << "// function " << on_success_impl.c_str() << ";" << endl; + indent(f_service_) << "// function onError(Dynamic) : Void;" << '\n'; + indent(f_service_) << "// function " << on_success_impl.c_str() << ";" << '\n'; } if (is_interface) { generate_deprecation_attribute(f_service_, tfunction, false); - indent(f_service_) << function_signature_combined(tfunction) << ";" << endl << endl; + indent(f_service_) << function_signature_combined(tfunction) << ";" << '\n' << '\n'; } else { - indent(f_service_) << "public " << function_signature_combined(tfunction) << " {" << endl; + indent(f_service_) << "public " << function_signature_combined(tfunction) << " {" << '\n'; } } @@ -1738,7 +1736,7 @@ void t_haxe_generator::generate_deprecation_attribute(ostream& out, t_function* } } - out << endl; + out << '\n'; } } @@ -1762,14 +1760,14 @@ void t_haxe_generator::generate_service_interface(t_service* tservice, bool comb generate_rtti_decoration(f_service_); generate_macro_decoration(f_service_); f_service_ << indent() << "interface " << get_cap_name(service_name_) << cbk_postfix << extends_iface << " {" - << endl << endl; + << '\n' << '\n'; indent_up(); for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { generate_haxe_doc(f_service_, *f_iter); generate_service_method_signature(*f_iter, true, combined); } indent_down(); - f_service_ << indent() << "}" << endl << endl; + f_service_ << indent() << "}" << '\n' << '\n'; } /** @@ -1778,7 +1776,7 @@ void t_haxe_generator::generate_service_interface(t_service* tservice, bool comb * @param tservice The service */ void t_haxe_generator::generate_service_helpers(t_service* tservice) { - f_service_ << endl << endl; + f_service_ << '\n' << '\n'; vector functions = tservice->get_functions(); vector::iterator f_iter; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { @@ -1804,44 +1802,44 @@ void t_haxe_generator::generate_service_client(t_service* tservice) { generate_rtti_decoration(f_service_); // build macro is inherited from interface indent(f_service_) << "class " << get_cap_name(service_name_) << "Impl" << extends_client - << " implements " << get_cap_name(service_name_) << " {" << endl << endl; + << " implements " << get_cap_name(service_name_) << " {" << '\n' << '\n'; indent_up(); - indent(f_service_) << "public function new( iprot : TProtocol, oprot : TProtocol = null)" << endl; + indent(f_service_) << "public function new( iprot : TProtocol, oprot : TProtocol = null)" << '\n'; scope_up(f_service_); if (extends.empty()) { - f_service_ << indent() << "iprot_ = iprot;" << endl; - f_service_ << indent() << "if (oprot == null) {" << endl; + f_service_ << indent() << "iprot_ = iprot;" << '\n'; + f_service_ << indent() << "if (oprot == null) {" << '\n'; indent_up(); - f_service_ << indent() << "oprot_ = iprot;" << endl; + f_service_ << indent() << "oprot_ = iprot;" << '\n'; indent_down(); - f_service_ << indent() << "} else {" << endl; + f_service_ << indent() << "} else {" << '\n'; indent_up(); - f_service_ << indent() << "oprot_ = oprot;" << endl; + f_service_ << indent() << "oprot_ = oprot;" << '\n'; indent_down(); - f_service_ << indent() << "}" << endl; + f_service_ << indent() << "}" << '\n'; } else { - f_service_ << indent() << "super(iprot, oprot);" << endl; + f_service_ << indent() << "super(iprot, oprot);" << '\n'; } scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; if (extends.empty()) { - f_service_ << indent() << "private var iprot_ : TProtocol;" << endl << indent() - << "private var oprot_ : TProtocol;" << endl << indent() - << "private var seqid_ : Int;" << endl << endl; + f_service_ << indent() << "private var iprot_ : TProtocol;" << '\n' << indent() + << "private var oprot_ : TProtocol;" << '\n' << indent() + << "private var seqid_ : Int;" << '\n' << '\n'; - indent(f_service_) << "public function getInputProtocol() : TProtocol" << endl; + indent(f_service_) << "public function getInputProtocol() : TProtocol" << '\n'; scope_up(f_service_); - indent(f_service_) << "return this.iprot_;" << endl; + indent(f_service_) << "return this.iprot_;" << '\n'; scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; - indent(f_service_) << "public function getOutputProtocol() : TProtocol" << endl; + indent(f_service_) << "public function getOutputProtocol() : TProtocol" << '\n'; scope_up(f_service_); - indent(f_service_) << "return this.oprot_;" << endl; + indent(f_service_) << "return this.oprot_;" << '\n'; scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; } // Generate client method implementations @@ -1866,140 +1864,140 @@ void t_haxe_generator::generate_service_client(t_service* tservice) { string args = tmp("args"); string calltype = (*f_iter)->is_oneway() ? "ONEWAY" : "CALL"; f_service_ << indent() << "oprot_.writeMessageBegin(new TMessage(\"" << funname - << "\", TMessageType." << calltype << ", seqid_));" << endl << indent() - << "var " << args << " : " << argsname << " = new " << argsname << "();" << endl; + << "\", TMessageType." << calltype << ", seqid_));" << '\n' << indent() + << "var " << args << " : " << argsname << " = new " << argsname << "();" << '\n'; for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) { f_service_ << indent() << args << "." << (*fld_iter)->get_name() << " = " - << (*fld_iter)->get_name() << ";" << endl; + << (*fld_iter)->get_name() << ";" << '\n'; } - f_service_ << indent() << args << ".write(oprot_);" << endl << indent() - << "oprot_.writeMessageEnd();" << endl; + f_service_ << indent() << args << ".write(oprot_);" << '\n' << indent() + << "oprot_.writeMessageEnd();" << '\n'; string retval = tmp("retval"); if (!((*f_iter)->is_oneway() || (*f_iter)->get_returntype()->is_void())) { f_service_ << indent() << "var " << retval << " : " << type_name((*f_iter)->get_returntype()) - << " = " << render_default_value_for_type((*f_iter)->get_returntype(),true) - << ";" << endl; + << " = " << render_default_value_for_type((*f_iter)->get_returntype(),true) + << ";" << '\n'; } if ((*f_iter)->is_oneway()) { - f_service_ << indent() << "oprot_.getTransport().flush();" << endl; + f_service_ << indent() << "oprot_.getTransport().flush();" << '\n'; } else { - indent(f_service_) << "oprot_.getTransport().flush(function(error:Dynamic) : Void {" << endl; + indent(f_service_) << "oprot_.getTransport().flush(function(error:Dynamic) : Void {" << '\n'; indent_up(); - indent(f_service_) << "try {" << endl; + indent(f_service_) << "try {" << '\n'; indent_up(); string appex = tmp("appex"); - indent(f_service_) << "var " << appex << " : TApplicationException;" << endl; + indent(f_service_) << "var " << appex << " : TApplicationException;" << '\n'; string resultname = get_cap_name((*f_iter)->get_name() + "_result"); - indent(f_service_) << "if (error != null) {" << endl; + indent(f_service_) << "if (error != null) {" << '\n'; indent_up(); - indent(f_service_) << "if (onError == null)" << endl; + indent(f_service_) << "if (onError == null)" << '\n'; indent_up(); - indent(f_service_) << "throw error;" << endl; + indent(f_service_) << "throw error;" << '\n'; indent_down(); - indent(f_service_) << "onError(error);" << endl; - indent(f_service_) << "return;" << endl; + indent(f_service_) << "onError(error);" << '\n'; + indent(f_service_) << "return;" << '\n'; indent_down(); - indent(f_service_) << "}" << endl << endl; + indent(f_service_) << "}" << '\n' << '\n'; string msg = tmp("msg"); - indent(f_service_) << "var " << msg << " : TMessage = iprot_.readMessageBegin();" << endl; - indent(f_service_) << "if (" << msg << ".type == TMessageType.EXCEPTION) {" << endl; + indent(f_service_) << "var " << msg << " : TMessage = iprot_.readMessageBegin();" << '\n'; + indent(f_service_) << "if (" << msg << ".type == TMessageType.EXCEPTION) {" << '\n'; indent_up(); - indent(f_service_) << appex << " = TApplicationException.read(iprot_);" << endl; - indent(f_service_) << "iprot_.readMessageEnd();" << endl; - indent(f_service_) << "if (onError == null)" << endl; + indent(f_service_) << appex << " = TApplicationException.read(iprot_);" << '\n'; + indent(f_service_) << "iprot_.readMessageEnd();" << '\n'; + indent(f_service_) << "if (onError == null)" << '\n'; indent_up(); - indent(f_service_) << "throw " << appex << ";" << endl; + indent(f_service_) << "throw " << appex << ";" << '\n'; indent_down(); - indent(f_service_) << "onError(" << appex << ");" << endl; - indent(f_service_) << "return;" << endl; + indent(f_service_) << "onError(" << appex << ");" << '\n'; + indent(f_service_) << "return;" << '\n'; indent_down(); - indent(f_service_) << "}" << endl << endl; + indent(f_service_) << "}" << '\n' << '\n'; string result = tmp("result"); - indent(f_service_) << "var " << result << " : " << resultname << " = new " << resultname << "();" << endl; - indent(f_service_) << "" << result << ".read(iprot_);" << endl; - indent(f_service_) << "iprot_.readMessageEnd();" << endl; + indent(f_service_) << "var " << result << " : " << resultname << " = new " << resultname << "();" << '\n'; + indent(f_service_) << "" << result << ".read(iprot_);" << '\n'; + indent(f_service_) << "iprot_.readMessageEnd();" << '\n'; // Careful, only return _result if not a void function if (!(*f_iter)->get_returntype()->is_void()) { - indent(f_service_) << "if (" << result << "." << generate_isset_check("success") << ") {" << endl; + indent(f_service_) << "if (" << result << "." << generate_isset_check("success") << ") {" << '\n'; indent_up(); - indent(f_service_) << "if (onSuccess != null)" << endl; + indent(f_service_) << "if (onSuccess != null)" << '\n'; indent_up(); - indent(f_service_) << "onSuccess(" << result << ".success);" << endl; + indent(f_service_) << "onSuccess(" << result << ".success);" << '\n'; indent_down(); - indent(f_service_) << retval << " = " << result << ".success;" << endl; - indent(f_service_) << "return;" << endl; + indent(f_service_) << retval << " = " << result << ".success;" << '\n'; + indent(f_service_) << "return;" << '\n'; indent_down(); - indent(f_service_) << "}" << endl << endl; + indent(f_service_) << "}" << '\n' << '\n'; } t_struct* xs = (*f_iter)->get_xceptions(); const std::vector& xceptions = xs->get_members(); vector::const_iterator x_iter; for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { - indent(f_service_) << "if (" << result << "." << (*x_iter)->get_name() << " != null) {" << endl; + indent(f_service_) << "if (" << result << "." << (*x_iter)->get_name() << " != null) {" << '\n'; indent_up(); - indent(f_service_) << "if (onError == null)" << endl; + indent(f_service_) << "if (onError == null)" << '\n'; indent_up(); - indent(f_service_) << "throw " << result << "." << (*x_iter)->get_name() << ";" << endl; + indent(f_service_) << "throw " << result << "." << (*x_iter)->get_name() << ";" << '\n'; indent_down(); - indent(f_service_) << "onError(" << result << "." << (*x_iter)->get_name() << ");" << endl; - indent(f_service_) << "return;" << endl; + indent(f_service_) << "onError(" << result << "." << (*x_iter)->get_name() << ");" << '\n'; + indent(f_service_) << "return;" << '\n'; indent_down(); - indent(f_service_) << "}" << endl << endl; + indent(f_service_) << "}" << '\n' << '\n'; } // If you get here it's an exception, unless a void function if ((*f_iter)->get_returntype()->is_void()) { - indent(f_service_) << "if (onSuccess != null)" << endl; + indent(f_service_) << "if (onSuccess != null)" << '\n'; indent_up(); - indent(f_service_) << "onSuccess();" << endl; + indent(f_service_) << "onSuccess();" << '\n'; indent_down(); - indent(f_service_) << "return;" << endl; + indent(f_service_) << "return;" << '\n'; } else { indent(f_service_) << appex << " = new TApplicationException(" << "TApplicationException.MISSING_RESULT," - << "\"" << (*f_iter)->get_name() << " failed: unknown result\");" << endl; - indent(f_service_) << "if (onError == null)" << endl; + << "\"" << (*f_iter)->get_name() << " failed: unknown result\");" << '\n'; + indent(f_service_) << "if (onError == null)" << '\n'; indent_up(); - indent(f_service_) << "throw " << appex << ";" << endl; + indent(f_service_) << "throw " << appex << ";" << '\n'; indent_down(); - indent(f_service_) << "onError(" << appex << ");" << endl; - indent(f_service_) << "return;" << endl; + indent(f_service_) << "onError(" << appex << ");" << '\n'; + indent(f_service_) << "return;" << '\n'; } indent_down(); - indent(f_service_) << endl; - indent(f_service_) << "} catch( e : TException) {" << endl; + indent(f_service_) << '\n'; + indent(f_service_) << "} catch( e : TException) {" << '\n'; indent_up(); - indent(f_service_) << "if (onError == null)" << endl; + indent(f_service_) << "if (onError == null)" << '\n'; indent_up(); - indent(f_service_) << "throw e;" << endl; + indent(f_service_) << "throw e;" << '\n'; indent_down(); - indent(f_service_) << "onError(e);" << endl; - indent(f_service_) << "return;" << endl; + indent(f_service_) << "onError(e);" << '\n'; + indent(f_service_) << "return;" << '\n'; indent_down(); - indent(f_service_) << "}" << endl; + indent(f_service_) << "}" << '\n'; indent_down(); - indent(f_service_) << "});" << endl << endl; + indent(f_service_) << "});" << '\n' << '\n'; } if (!((*f_iter)->is_oneway() || (*f_iter)->get_returntype()->is_void())) { - f_service_ << indent() << "return " << retval << ";" << endl; + f_service_ << indent() << "return " << retval << ";" << '\n'; } // Close function scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; } indent_down(); - indent(f_service_) << "}" << endl; + indent(f_service_) << "}" << '\n'; } /** @@ -2024,35 +2022,35 @@ void t_haxe_generator::generate_service_server(t_service* tservice) { generate_rtti_decoration(f_service_); generate_macro_decoration(f_service_); indent(f_service_) << "class " << get_cap_name(service_name_) << "Processor" << extends_processor - << " implements TProcessor {" << endl << endl; + << " implements TProcessor {" << '\n' << '\n'; indent_up(); f_service_ << indent() << "private var " << get_cap_name(service_name_) - << "_iface_ : " << get_cap_name(service_name_) << "_service;" << endl; + << "_iface_ : " << get_cap_name(service_name_) << "_service;" << '\n'; if (extends.empty()) { f_service_ << indent() << "private var PROCESS_MAP = new StringMap< Int->TProtocol->TProtocol->Void >();" - << endl; + << '\n'; } - f_service_ << endl; + f_service_ << '\n'; indent(f_service_) << "public function new( iface : " << get_cap_name(service_name_) << "_service)" - << endl; + << '\n'; scope_up(f_service_); if (!extends.empty()) { - f_service_ << indent() << "super(iface);" << endl; + f_service_ << indent() << "super(iface);" << '\n'; } - f_service_ << indent() << get_cap_name(service_name_) << "_iface_ = iface;" << endl; + f_service_ << indent() << get_cap_name(service_name_) << "_iface_ = iface;" << '\n'; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { f_service_ << indent() << "PROCESS_MAP.set(\"" << (*f_iter)->get_name() << "\", " - << (*f_iter)->get_name() << "());" << endl; + << (*f_iter)->get_name() << "());" << '\n'; } scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; // Generate the server implementation string override = ""; @@ -2061,31 +2059,31 @@ void t_haxe_generator::generate_service_server(t_service* tservice) { } indent(f_service_) << override << "public function process( iprot : TProtocol, oprot : TProtocol) : Bool" - << endl; + << '\n'; scope_up(f_service_); - f_service_ << indent() << "var msg : TMessage = iprot.readMessageBegin();" << endl; + f_service_ << indent() << "var msg : TMessage = iprot.readMessageBegin();" << '\n'; // TODO(mcslee): validate message, was the seqid etc. legit? f_service_ - << indent() << "var fn = PROCESS_MAP.get(msg.name);" << endl - << indent() << "if (fn == null) {" << endl - << indent() << " TProtocolUtil.skip(iprot, TType.STRUCT);" << endl - << indent() << " iprot.readMessageEnd();" << endl + << indent() << "var fn = PROCESS_MAP.get(msg.name);" << '\n' + << indent() << "if (fn == null) {" << '\n' + << indent() << " TProtocolUtil.skip(iprot, TType.STRUCT);" << '\n' + << indent() << " iprot.readMessageEnd();" << '\n' << indent() << " var appex = new TApplicationException(TApplicationException.UNKNOWN_METHOD, " - << "\"Invalid method name: '\"+msg.name+\"'\");" << endl - << indent() << " oprot.writeMessageBegin(new TMessage(msg.name, TMessageType.EXCEPTION, msg.seqid));" << endl - << indent() << " appex.write(oprot);" << endl << indent() << " oprot.writeMessageEnd();" << endl - << indent() << " oprot.getTransport().flush();" << endl - << indent() << " return true;" << endl << indent() << "}" << endl - << indent() << "fn( msg.seqid, iprot, oprot);" << endl + << "\"Invalid method name: '\"+msg.name+\"'\");" << '\n' + << indent() << " oprot.writeMessageBegin(new TMessage(msg.name, TMessageType.EXCEPTION, msg.seqid));" << '\n' + << indent() << " appex.write(oprot);" << '\n' << indent() << " oprot.writeMessageEnd();" << '\n' + << indent() << " oprot.getTransport().flush();" << '\n' + << indent() << " return true;" << '\n' << indent() << "}" << '\n' + << indent() << "fn( msg.seqid, iprot, oprot);" << '\n' ; - f_service_ << indent() << "return true;" << endl; + f_service_ << indent() << "return true;" << '\n'; scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; // Generate the process subfunctions for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { @@ -2093,7 +2091,7 @@ void t_haxe_generator::generate_service_server(t_service* tservice) { } indent_down(); - indent(f_service_) << "}" << endl << endl; + indent(f_service_) << "}" << '\n' << '\n'; } /** @@ -2132,20 +2130,20 @@ void t_haxe_generator::generate_process_function(t_service* tservice, t_function (void)tservice; // Open class indent(f_service_) << "private function " << tfunction->get_name() - << "() : Int->TProtocol->TProtocol->Void {" << endl; + << "() : Int->TProtocol->TProtocol->Void {" << '\n'; indent_up(); // Open function indent(f_service_) << "return function( seqid : Int, iprot : TProtocol, oprot : TProtocol) : Void" - << endl; + << '\n'; scope_up(f_service_); string argsname = get_cap_name(tfunction->get_name() + "_args"); string resultname = get_cap_name(tfunction->get_name() + "_result"); - f_service_ << indent() << "var args : " << argsname << " = new " << argsname << "();" << endl - << indent() << "args.read(iprot);" << endl << indent() << "iprot.readMessageEnd();" - << endl; + f_service_ << indent() << "var args : " << argsname << " = new " << argsname << "();" << '\n' + << indent() << "args.read(iprot);" << '\n' << indent() << "iprot.readMessageEnd();" + << '\n'; t_struct* xs = tfunction->get_xceptions(); const std::vector& xceptions = xs->get_members(); @@ -2153,11 +2151,11 @@ void t_haxe_generator::generate_process_function(t_service* tservice, t_function // Declare result for non oneway function if (!tfunction->is_oneway()) { - f_service_ << indent() << "var result : " << resultname << " = new " << resultname << "();" << endl; + f_service_ << indent() << "var result : " << resultname << " = new " << resultname << "();" << '\n'; } // Try block for any function to catch (defined or undefined) exceptions - f_service_ << indent() << "try {" << endl; + f_service_ << indent() << "try {" << '\n'; indent_up(); @@ -2182,7 +2180,7 @@ void t_haxe_generator::generate_process_function(t_service* tservice, t_function } f_service_ << "args." << (*f_iter)->get_name(); } - f_service_ << ");" << endl; + f_service_ << ");" << '\n'; indent_down(); f_service_ << indent() << "}"; @@ -2190,11 +2188,11 @@ void t_haxe_generator::generate_process_function(t_service* tservice, t_function // catch exceptions defined in the IDL for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { f_service_ << " catch (" << (*x_iter)->get_name() << ":" - << get_cap_name(type_name((*x_iter)->get_type(), false, false)) << ") {" << endl; + << get_cap_name(type_name((*x_iter)->get_type(), false, false)) << ") {" << '\n'; if (!tfunction->is_oneway()) { indent_up(); f_service_ << indent() << "result." << (*x_iter)->get_name() << " = " - << (*x_iter)->get_name() << ";" << endl; + << (*x_iter)->get_name() << ";" << '\n'; indent_down(); f_service_ << indent() << "}"; } else { @@ -2205,45 +2203,45 @@ void t_haxe_generator::generate_process_function(t_service* tservice, t_function // always catch all exceptions to prevent from service denial string appex = tmp("appex"); - f_service_ << " catch (th : Dynamic) {" << endl; + f_service_ << " catch (th : Dynamic) {" << '\n'; indent_up(); - indent(f_service_) << "trace(\"Internal error processing " << tfunction->get_name() << "\", th);" << endl; + indent(f_service_) << "trace(\"Internal error processing " << tfunction->get_name() << "\", th);" << '\n'; if (!tfunction->is_oneway()) { indent(f_service_) << "var appex = new TApplicationException(TApplicationException.INTERNAL_ERROR, " - "\"Internal error processing " << tfunction->get_name() << "\");" << endl; + "\"Internal error processing " << tfunction->get_name() << "\");" << '\n'; indent(f_service_) << "oprot.writeMessageBegin(new TMessage(\"" << tfunction->get_name() - << "\", TMessageType.EXCEPTION, seqid));" << endl; - indent(f_service_) << "appex.write(oprot);" << endl; - indent(f_service_) << "oprot.writeMessageEnd();" << endl; - indent(f_service_) << "oprot.getTransport().flush();" << endl; + << "\", TMessageType.EXCEPTION, seqid));" << '\n'; + indent(f_service_) << "appex.write(oprot);" << '\n'; + indent(f_service_) << "oprot.writeMessageEnd();" << '\n'; + indent(f_service_) << "oprot.getTransport().flush();" << '\n'; } - indent(f_service_) << "return;" << endl; + indent(f_service_) << "return;" << '\n'; indent_down(); - f_service_ << indent() << "}" << endl; + f_service_ << indent() << "}" << '\n'; // Shortcut out here for oneway functions if (tfunction->is_oneway()) { - f_service_ << indent() << "return;" << endl; + f_service_ << indent() << "return;" << '\n'; scope_down(f_service_); // Close class indent_down(); - f_service_ << indent() << "}" << endl << endl; + f_service_ << indent() << "}" << '\n' << '\n'; return; } f_service_ << indent() << "oprot.writeMessageBegin(new TMessage(\"" << tfunction->get_name() - << "\", TMessageType.REPLY, seqid));" << endl << indent() << "result.write(oprot);" - << endl << indent() << "oprot.writeMessageEnd();" << endl << indent() - << "oprot.getTransport().flush();" << endl; + << "\", TMessageType.REPLY, seqid));" << '\n' << indent() << "result.write(oprot);" + << '\n' << indent() << "oprot.writeMessageEnd();" << '\n' << indent() + << "oprot.getTransport().flush();" << '\n'; // Close function scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; // Close class indent_down(); - f_service_ << indent() << "}" << endl << endl; + f_service_ << indent() << "}" << '\n' << '\n'; } /** @@ -2309,7 +2307,7 @@ void t_haxe_generator::generate_deserialize_field(ostream& out, t_field* tfield, } else if (type->is_enum()) { out << "readI32();"; } - out << endl; + out << '\n'; } else { printf("DO NOT KNOW HOW TO DESERIALIZE FIELD '%s' TYPE '%s'\n", tfield->get_name().c_str(), @@ -2323,8 +2321,8 @@ void t_haxe_generator::generate_deserialize_field(ostream& out, t_field* tfield, void t_haxe_generator::generate_deserialize_struct(ostream& out, t_struct* tstruct, string prefix) { - out << indent() << prefix << " = new " << get_cap_name(type_name(tstruct)) << "();" << endl - << indent() << prefix << ".read(iprot);" << endl; + out << indent() << prefix << " = new " << get_cap_name(type_name(tstruct)) << "();" << '\n' + << indent() << prefix << ".read(iprot);" << '\n'; } /** @@ -2345,21 +2343,21 @@ void t_haxe_generator::generate_deserialize_container(ostream& out, t_type* ttyp // Declare variables, read header if (ttype->is_map()) { - indent(out) << "var " << obj << " = iprot.readMapBegin();" << endl; + indent(out) << "var " << obj << " = iprot.readMapBegin();" << '\n'; } else if (ttype->is_set()) { - indent(out) << "var " << obj << " = iprot.readSetBegin();" << endl; + indent(out) << "var " << obj << " = iprot.readSetBegin();" << '\n'; } else if (ttype->is_list()) { - indent(out) << "var " << obj << " = iprot.readListBegin();" << endl; + indent(out) << "var " << obj << " = iprot.readListBegin();" << '\n'; } indent(out) << prefix << " = new " << type_name(ttype, false, true) // size the collection correctly << "(" - << ");" << endl; + << ");" << '\n'; // For loop iterates over elements string i = tmp("_i"); - indent(out) << "for( " << i << " in 0 ... " << obj << ".size)" << endl; + indent(out) << "for( " << i << " in 0 ... " << obj << ".size)" << '\n'; scope_up(out); @@ -2375,11 +2373,11 @@ void t_haxe_generator::generate_deserialize_container(ostream& out, t_type* ttyp // Read container end if (ttype->is_map()) { - indent(out) << "iprot.readMapEnd();" << endl; + indent(out) << "iprot.readMapEnd();" << '\n'; } else if (ttype->is_set()) { - indent(out) << "iprot.readSetEnd();" << endl; + indent(out) << "iprot.readSetEnd();" << '\n'; } else if (ttype->is_list()) { - indent(out) << "iprot.readListEnd();" << endl; + indent(out) << "iprot.readListEnd();" << '\n'; } scope_down(out); @@ -2394,13 +2392,13 @@ void t_haxe_generator::generate_deserialize_map_element(ostream& out, t_map* tma t_field fkey(tmap->get_key_type(), key); t_field fval(tmap->get_val_type(), val); - indent(out) << declare_field(&fkey) << endl; - indent(out) << declare_field(&fval) << endl; + indent(out) << declare_field(&fkey) << '\n'; + indent(out) << declare_field(&fval) << '\n'; generate_deserialize_field(out, &fkey); generate_deserialize_field(out, &fval); - indent(out) << prefix << ".set( " << key << ", " << val << ");" << endl; + indent(out) << prefix << ".set( " << key << ", " << val << ");" << '\n'; } /** @@ -2410,11 +2408,11 @@ void t_haxe_generator::generate_deserialize_set_element(ostream& out, t_set* tse string elem = tmp("_elem"); t_field felem(tset->get_elem_type(), elem); - indent(out) << declare_field(&felem) << endl; + indent(out) << declare_field(&felem) << '\n'; generate_deserialize_field(out, &felem); - indent(out) << prefix << ".add(" << elem << ");" << endl; + indent(out) << prefix << ".add(" << elem << ");" << '\n'; } /** @@ -2426,11 +2424,11 @@ void t_haxe_generator::generate_deserialize_list_element(ostream& out, string elem = tmp("_elem"); t_field felem(tlist->get_elem_type(), elem); - indent(out) << declare_field(&felem) << endl; + indent(out) << declare_field(&felem) << '\n'; generate_deserialize_field(out, &felem); - indent(out) << prefix << ".add(" << elem << ");" << endl; + indent(out) << prefix << ".add(" << elem << ");" << '\n'; } /** @@ -2496,7 +2494,7 @@ void t_haxe_generator::generate_serialize_field(ostream& out, t_field* tfield, s } else if (type->is_enum()) { out << "writeI32(" << name << ");"; } - out << endl; + out << '\n'; } else { printf("DO NOT KNOW HOW TO SERIALIZE FIELD '%s%s' TYPE '%s'\n", prefix.c_str(), @@ -2513,7 +2511,7 @@ void t_haxe_generator::generate_serialize_field(ostream& out, t_field* tfield, s */ void t_haxe_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix) { (void)tstruct; - out << indent() << prefix << ".write(oprot);" << endl; + out << indent() << prefix << ".write(oprot);" << '\n'; } /** @@ -2527,30 +2525,30 @@ void t_haxe_generator::generate_serialize_container(ostream& out, t_type* ttype, if (ttype->is_map()) { string iter = tmp("_key"); string counter = tmp("_sizeCounter"); - indent(out) << "var " << counter << " : Int = 0;" << endl; - indent(out) << "for( " << iter << " in " << prefix << ") {" << endl; - indent(out) << " " << counter << +"++;" << endl; - indent(out) << "}" << endl; + indent(out) << "var " << counter << " : Int = 0;" << '\n'; + indent(out) << "for( " << iter << " in " << prefix << ") {" << '\n'; + indent(out) << " " << counter << +"++;" << '\n'; + indent(out) << "}" << '\n'; indent(out) << "oprot.writeMapBegin(new TMap(" << type_to_enum(((t_map*)ttype)->get_key_type()) << ", " << type_to_enum(((t_map*)ttype)->get_val_type()) << ", " << counter << "));" - << endl; + << '\n'; } else if (ttype->is_set()) { indent(out) << "oprot.writeSetBegin(new TSet(" << type_to_enum(((t_set*)ttype)->get_elem_type()) - << ", " << prefix << ".size));" << endl; + << ", " << prefix << ".size));" << '\n'; } else if (ttype->is_list()) { indent(out) << "oprot.writeListBegin(new TList(" << type_to_enum(((t_list*)ttype)->get_elem_type()) << ", " << prefix << ".length));" - << endl; + << '\n'; } string iter = tmp("elem"); if (ttype->is_map()) { - indent(out) << "for( " << iter << " in " << prefix << ".keys())" << endl; + indent(out) << "for( " << iter << " in " << prefix << ".keys())" << '\n'; } else if (ttype->is_set()) { - indent(out) << "for( " << iter << " in " << prefix << ".toArray())" << endl; + indent(out) << "for( " << iter << " in " << prefix << ".toArray())" << '\n'; } else if (ttype->is_list()) { - indent(out) << "for( " << iter << " in " << prefix << ")" << endl; + indent(out) << "for( " << iter << " in " << prefix << ")" << '\n'; } scope_up(out); @@ -2566,11 +2564,11 @@ void t_haxe_generator::generate_serialize_container(ostream& out, t_type* ttype, scope_down(out); if (ttype->is_map()) { - indent(out) << "oprot.writeMapEnd();" << endl; + indent(out) << "oprot.writeMapEnd();" << '\n'; } else if (ttype->is_set()) { - indent(out) << "oprot.writeSetEnd();" << endl; + indent(out) << "oprot.writeSetEnd();" << '\n'; } else if (ttype->is_list()) { - indent(out) << "oprot.writeListEnd();" << endl; + indent(out) << "oprot.writeListEnd();" << '\n'; } } @@ -3006,7 +3004,7 @@ string t_haxe_generator::constant_name(string name) { */ void t_haxe_generator::generate_rtti_decoration(ostream& out) { if (rtti_) { - out << "@:rtti" << endl; + out << "@:rtti" << '\n'; } } @@ -3015,10 +3013,10 @@ void t_haxe_generator::generate_rtti_decoration(ostream& out) { */ void t_haxe_generator::generate_macro_decoration(ostream& out) { if (!buildmacro_.empty()) { - out << "#if ! macro" << endl; - out << "@:build( " << buildmacro_ << ")" << endl; // current class/interface - out << "@:autoBuild( " << buildmacro_ << ")" << endl; // inherited classes/interfaces - out << "#end" << endl; + out << "#if ! macro" << '\n'; + out << "@:build( " << buildmacro_ << ")" << '\n'; // current class/interface + out << "@:autoBuild( " << buildmacro_ << ")" << '\n'; // inherited classes/interfaces + out << "#end" << '\n'; } } @@ -3061,7 +3059,7 @@ std::string t_haxe_generator::generate_isset_check(std::string field_name) { void t_haxe_generator::generate_isset_set(ostream& out, t_field* field) { if (!type_can_be_null(field->get_type())) { - indent(out) << "this.__isset_" << field->get_name() << " = true;" << endl; + indent(out) << "this.__isset_" << field->get_name() << " = true;" << '\n'; } } diff --git a/compiler/cpp/src/thrift/generate/t_html_generator.cc b/compiler/cpp/src/thrift/generate/t_html_generator.cc index 15a0401d596..637cd885eff 100644 --- a/compiler/cpp/src/thrift/generate/t_html_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_html_generator.cc @@ -38,8 +38,6 @@ using std::string; using std::stringstream; using std::vector; -static const string endl = "\n"; // avoid ostream << std::endl flushes - enum input_type { INPUT_UNKNOWN, INPUT_UTF8, INPUT_PLAIN }; /** @@ -129,9 +127,9 @@ class t_html_generator : public t_generator { void t_html_generator::generate_program_toc() { f_out_ << "" - << "" << endl; + << "" << '\n'; generate_program_toc_row(program_); - f_out_ << "
ModuleServicesData typesConstants
Data typesConstants
" << endl; + f_out_ << "" << '\n'; } /** @@ -159,15 +157,15 @@ void t_html_generator::generate_program_toc_rows(t_program* tprog, */ void t_html_generator::generate_program_toc_row(t_program* tprog) { string fname = tprog->get_name() + ".html"; - f_out_ << "" << endl << "" << tprog->get_name() << ""; + f_out_ << "" << '\n' << "" << tprog->get_name() << ""; if (!tprog->get_services().empty()) { vector services = tprog->get_services(); vector::iterator sv_iter; for (sv_iter = services.begin(); sv_iter != services.end(); ++sv_iter) { string name = get_service_name(*sv_iter); f_out_ << "" << name - << "
" << endl; - f_out_ << "
    " << endl; + << "
    " << '\n'; + f_out_ << "
      " << '\n'; map fn_html; vector functions = (*sv_iter)->get_functions(); vector::iterator fn_iter; @@ -178,12 +176,12 @@ void t_html_generator::generate_program_toc_row(t_program* tprog) { fn_html.insert(pair(fn_name, html)); } for (auto & html_iter : fn_html) { - f_out_ << html_iter.second << endl; + f_out_ << html_iter.second << '\n'; } - f_out_ << "
    " << endl; + f_out_ << "
" << '\n'; } } - f_out_ << "" << endl << ""; + f_out_ << "" << '\n' << ""; map data_types; if (!tprog->get_enums().empty()) { vector enums = tprog->get_enums(); @@ -191,7 +189,7 @@ void t_html_generator::generate_program_toc_row(t_program* tprog) { for (en_iter = enums.begin(); en_iter != enums.end(); ++en_iter) { string name = (*en_iter)->get_name(); // f_out_ << "" << name - // << "
" << endl; + // << "
" << '\n'; string html = "" + name + ""; data_types.insert(pair(name, html)); } @@ -202,7 +200,7 @@ void t_html_generator::generate_program_toc_row(t_program* tprog) { for (td_iter = typedefs.begin(); td_iter != typedefs.end(); ++td_iter) { string name = (*td_iter)->get_symbolic(); // f_out_ << "" << name - // << "
" << endl; + // << "
" << '\n'; string html = "" + name + ""; data_types.insert(pair(name, html)); @@ -214,16 +212,16 @@ void t_html_generator::generate_program_toc_row(t_program* tprog) { for (o_iter = objects.begin(); o_iter != objects.end(); ++o_iter) { string name = (*o_iter)->get_name(); // f_out_ << "" << name - //<< "
" << endl; + //<< "
" << '\n'; string html = "" + name + ""; data_types.insert(pair(name, html)); } } for (auto & data_type : data_types) { - f_out_ << data_type.second << "
" << endl; + f_out_ << data_type.second << "
" << '\n'; } - f_out_ << "" << endl << ""; + f_out_ << "" << '\n' << ""; if (!tprog->get_consts().empty()) { map const_html; vector consts = tprog->get_consts(); @@ -235,10 +233,10 @@ void t_html_generator::generate_program_toc_row(t_program* tprog) { const_html.insert(pair(name, html)); } for (auto & con_iter : const_html) { - f_out_ << con_iter.second << "
" << endl; + f_out_ << con_iter.second << "
" << '\n'; } } - f_out_ << "" << endl << ""; + f_out_ << "" << '\n' << ""; } /** @@ -251,30 +249,30 @@ void t_html_generator::generate_program() { current_file_ = program_->get_name() + ".html"; string fname = get_out_dir() + current_file_; f_out_.open(fname.c_str()); - f_out_ << "" << endl; - f_out_ << "" << endl; - f_out_ << "" << endl; - f_out_ << "" << endl; + f_out_ << "" << '\n'; + f_out_ << "" << '\n'; + f_out_ << "" << '\n'; + f_out_ << "" << '\n'; generate_style_tag(); - f_out_ << "Thrift module: " << program_->get_name() << "" << endl - << "
" << endl - << "

Thrift module: " << program_->get_name() << "

" << endl; + f_out_ << "Thrift module: " << program_->get_name() << "" << '\n' + << "
" << '\n' + << "

Thrift module: " << program_->get_name() << "

" << '\n'; print_doc(program_); generate_program_toc(); if (!program_->get_consts().empty()) { - f_out_ << "

Constants

" << endl; + f_out_ << "

Constants

" << '\n'; vector consts = program_->get_consts(); f_out_ << ""; - f_out_ << "" << endl; + f_out_ << "" << '\n'; generate_consts(consts); f_out_ << "
ConstantTypeValue
ConstantTypeValue
"; } if (!program_->get_enums().empty()) { - f_out_ << "

Enumerations

" << endl; + f_out_ << "

Enumerations

" << '\n'; // Generate enums vector enums = program_->get_enums(); vector::iterator en_iter; @@ -284,7 +282,7 @@ void t_html_generator::generate_program() { } if (!program_->get_typedefs().empty()) { - f_out_ << "

Type declarations

" << endl; + f_out_ << "

Type declarations

" << '\n'; // Generate typedefs vector typedefs = program_->get_typedefs(); vector::iterator td_iter; @@ -294,7 +292,7 @@ void t_html_generator::generate_program() { } if (!program_->get_objects().empty()) { - f_out_ << "

Data structures

" << endl; + f_out_ << "

Data structures

" << '\n'; // Generate structs and exceptions in declared order vector objects = program_->get_objects(); vector::iterator o_iter; @@ -308,7 +306,7 @@ void t_html_generator::generate_program() { } if (!program_->get_services().empty()) { - f_out_ << "

Services

" << endl; + f_out_ << "

Services

" << '\n'; // Generate services vector services = program_->get_services(); vector::iterator sv_iter; @@ -318,7 +316,7 @@ void t_html_generator::generate_program() { } } - f_out_ << "
" << endl; + f_out_ << "
" << '\n'; f_out_.close(); generate_index(); @@ -332,17 +330,17 @@ void t_html_generator::generate_index() { current_file_ = "index.html"; string index_fname = get_out_dir() + current_file_; f_out_.open(index_fname.c_str()); - f_out_ << "" << endl << "" << endl; + f_out_ << "" << '\n' << "" << '\n'; generate_style_tag(); - f_out_ << "All Thrift declarations" << endl - << "
" << endl << "

All Thrift declarations

" << endl; + f_out_ << "All Thrift declarations" << '\n' + << "
" << '\n' << "

All Thrift declarations

" << '\n'; f_out_ << "" - << "" << endl; + << "" << '\n'; vector programs; generate_program_toc_rows(program_, programs); - f_out_ << "
ModuleServicesData typesConstants
Constants
" << endl; - f_out_ << "
" << endl; + f_out_ << "" << '\n'; + f_out_ << "
" << '\n'; f_out_.close(); } @@ -357,17 +355,17 @@ void t_html_generator::generate_css() { } void t_html_generator::generate_css_content(std::ostream& f_target) { - f_target << BOOTSTRAP_CSS() << endl; - f_target << "/* Auto-generated CSS for generated Thrift docs */" << endl; - f_target << "h3, h4 { margin-bottom: 6px; }" << endl; + f_target << BOOTSTRAP_CSS() << '\n'; + f_target << "/* Auto-generated CSS for generated Thrift docs */" << '\n'; + f_target << "h3, h4 { margin-bottom: 6px; }" << '\n'; f_target << "div.definition { border: 1px solid #CCC; margin-bottom: 10px; padding: 10px; }" - << endl; - f_target << "div.extends { margin: -0.5em 0 1em 5em }" << endl; - f_target << "td { vertical-align: top; }" << endl; - f_target << "table { empty-cells: show; }" << endl; - f_target << "code { line-height: 20px; }" << endl; + << '\n'; + f_target << "div.extends { margin: -0.5em 0 1em 5em }" << '\n'; + f_target << "td { vertical-align: top; }" << '\n'; + f_target << "table { empty-cells: show; }" << '\n'; + f_target << "code { line-height: 20px; }" << '\n'; f_target << ".table-bordered th, .table-bordered td { border-bottom: 1px solid #DDDDDD; }" - << endl; + << '\n'; } /** @@ -377,11 +375,11 @@ void t_html_generator::generate_css_content(std::ostream& f_target) { */ void t_html_generator::generate_style_tag() { if (!standalone_) { - f_out_ << "" << endl; + f_out_ << "" << '\n'; } else { - f_out_ << "" << endl; + f_out_ << "-->" << '\n'; } } @@ -856,14 +854,14 @@ void t_html_generator::print_fn_args_doc(t_function* tfunction) { if (has_docs) { arg_iter = args.begin(); f_out_ << "

get_name() - << "\">Parameters

" << endl; + << "\">Parameters" << '\n'; f_out_ << ""; f_out_ << ""; for (; arg_iter != args.end(); arg_iter++) { f_out_ << "" << endl; + f_out_ << "" << '\n'; } f_out_ << "
NameDescription
" << (*arg_iter)->get_name(); f_out_ << ""; f_out_ << escape_html((*arg_iter)->get_doc()); - f_out_ << "
"; } @@ -880,14 +878,14 @@ void t_html_generator::print_fn_args_doc(t_function* tfunction) { if (has_docs) { ex_iter = excepts.begin(); f_out_ << "

get_name() - << "\">Exceptions

" << endl; + << "\">Exceptions" << '\n'; f_out_ << ""; f_out_ << ""; for (; ex_iter != excepts.end(); ex_iter++) { f_out_ << "" << endl; + f_out_ << "" << '\n'; } f_out_ << "
TypeDescription
" << (*ex_iter)->get_type()->get_name(); f_out_ << ""; f_out_ << escape_html((*ex_iter)->get_doc()); - f_out_ << "
"; } @@ -902,12 +900,12 @@ void t_html_generator::print_fn_args_doc(t_function* tfunction) { void t_html_generator::generate_typedef(t_typedef* ttypedef) { string name = ttypedef->get_name(); f_out_ << "
"; - f_out_ << "

Typedef: " << name << "

" << endl; + f_out_ << "

Typedef: " << name << "

" << '\n'; f_out_ << "

Base type: "; print_type(ttypedef->get_type()); - f_out_ << "

" << endl; + f_out_ << "

" << '\n'; print_doc(ttypedef); - f_out_ << "
" << endl; + f_out_ << "" << '\n'; } /** @@ -918,21 +916,21 @@ void t_html_generator::generate_typedef(t_typedef* ttypedef) { void t_html_generator::generate_enum(t_enum* tenum) { string name = tenum->get_name(); f_out_ << "
"; - f_out_ << "

Enumeration: " << name << "

" << endl; + f_out_ << "

Enumeration: " << name << "

" << '\n'; print_doc(tenum); vector values = tenum->get_constants(); vector::iterator val_iter; - f_out_ << "
" << endl; + f_out_ << "
" << '\n'; for (val_iter = values.begin(); val_iter != values.end(); ++val_iter) { f_out_ << "" << endl; + f_out_ << "" << '\n'; } - f_out_ << "
"; f_out_ << (*val_iter)->get_name(); f_out_ << ""; f_out_ << (*val_iter)->get_value(); - f_out_ << "" << endl; + f_out_ << "" << '\n'; print_doc((*val_iter)); - f_out_ << "
" << endl; + f_out_ << "" << '\n'; } /** @@ -968,12 +966,12 @@ void t_html_generator::generate_struct(t_struct* tstruct) { } else { f_out_ << "Struct: "; } - f_out_ << name << "" << endl; + f_out_ << name << "" << '\n'; vector members = tstruct->get_members(); vector::iterator mem_iter = members.begin(); f_out_ << ""; f_out_ << "" << endl; + "th>" << '\n'; for (; mem_iter != members.end(); mem_iter++) { f_out_ << "" << endl; + f_out_ << "" << '\n'; } f_out_ << "
KeyFieldTypeDescriptionRequirednessDefault value
Default value
" << (*mem_iter)->get_key() << ""; f_out_ << (*mem_iter)->get_name(); @@ -996,7 +994,7 @@ void t_html_generator::generate_struct(t_struct* tstruct) { print_const_value((*mem_iter)->get_type(), default_val); f_out_ << ""; } - f_out_ << "

"; print_doc(tstruct); @@ -1018,7 +1016,7 @@ void t_html_generator::generate_xception(t_struct* txception) { * @param tservice The service definition */ void t_html_generator::generate_service(t_service* tservice) { - f_out_ << "

Service: " << service_name_ << "

" << endl; + f_out_ << "

Service: " << service_name_ << "

" << '\n'; if (tservice->get_extends()) { f_out_ << "
extends "; @@ -1032,7 +1030,7 @@ void t_html_generator::generate_service(t_service* tservice) { string fn_name = (*fn_iter)->get_name(); f_out_ << "
"; f_out_ << "

Function: " << service_name_ - << "." << fn_name << "

" << endl; + << "." << fn_name << "" << '\n'; f_out_ << "
";
     std::string::size_type offset = print_type((*fn_iter)->get_returntype());
     bool first = true;
@@ -1042,7 +1040,7 @@ void t_html_generator::generate_service(t_service* tservice) {
     vector::iterator arg_iter = args.begin();
     for (; arg_iter != args.end(); arg_iter++) {
       if (!first) {
-        f_out_ << "," << endl;
+        f_out_ << "," << '\n';
         for (std::string::size_type i = 0; i < offset; ++i) {
           f_out_ << " ";
         }
@@ -1055,7 +1053,7 @@ void t_html_generator::generate_service(t_service* tservice) {
         print_const_value((*arg_iter)->get_type(), (*arg_iter)->get_value());
       }
     }
-    f_out_ << ")" << endl;
+    f_out_ << ")" << '\n';
     first = true;
     vector excepts = (*fn_iter)->get_xceptions()->get_members();
     vector::iterator ex_iter = excepts.begin();
@@ -1068,7 +1066,7 @@ void t_html_generator::generate_service(t_service* tservice) {
         first = false;
         print_type((*ex_iter)->get_type());
       }
-      f_out_ << endl;
+      f_out_ << '\n';
     }
     f_out_ << "
"; print_doc(*fn_iter); diff --git a/compiler/cpp/src/thrift/generate/t_java_generator.cc b/compiler/cpp/src/thrift/generate/t_java_generator.cc index 1617e0f91f4..1467f843d56 100644 --- a/compiler/cpp/src/thrift/generate/t_java_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_java_generator.cc @@ -45,8 +45,6 @@ using std::string; using std::stringstream; using std::vector; -static const string endl = "\n"; // avoid ostream << std::endl flushes - static const string thrift_option_class = "org.apache.thrift.Option"; static const string jdk_option_class = "java.util.Optional"; @@ -521,8 +519,7 @@ string t_java_generator::java_package() { } string t_java_generator::java_suppressions() { - return "@SuppressWarnings({\"cast\", \"rawtypes\", \"serial\", \"unchecked\", \"unused\"})" - + endl; + return "@SuppressWarnings({\"cast\", \"rawtypes\", \"serial\", \"unchecked\", \"unused\"})\n"; } string t_java_generator::java_nullable_annotation() { @@ -577,7 +574,7 @@ void t_java_generator::generate_enum(t_enum* tenum) { f_enum.open(f_enum_name.c_str()); // Comment and package it - f_enum << autogen_comment() << java_package() << endl; + f_enum << autogen_comment() << java_package() << '\n'; generate_java_doc(f_enum, tenum); @@ -586,7 +583,7 @@ void t_java_generator::generate_enum(t_enum* tenum) { } if (is_deprecated) { - indent(f_enum) << "@Deprecated" << endl; + indent(f_enum) << "@Deprecated" << '\n'; } indent(f_enum) << "public enum " << tenum->get_name() << " implements org.apache.thrift.TEnum "; scope_up(f_enum); @@ -600,62 +597,62 @@ void t_java_generator::generate_enum(t_enum* tenum) { if (first) { first = false; } else { - f_enum << "," << endl; + f_enum << "," << '\n'; } generate_java_doc(f_enum, *c_iter); if (this->is_deprecated((*c_iter)->annotations_)) { - indent(f_enum) << "@Deprecated" << endl; + indent(f_enum) << "@Deprecated" << '\n'; } indent(f_enum) << (*c_iter)->get_name() << "(" << value << ")"; } - f_enum << ";" << endl << endl; + f_enum << ";" << '\n' << '\n'; // Field for thriftCode - indent(f_enum) << "private final int value;" << endl << endl; + indent(f_enum) << "private final int value;" << '\n' << '\n'; - indent(f_enum) << "private " << tenum->get_name() << "(int value) {" << endl; - indent(f_enum) << " this.value = value;" << endl; - indent(f_enum) << "}" << endl << endl; + indent(f_enum) << "private " << tenum->get_name() << "(int value) {" << '\n'; + indent(f_enum) << " this.value = value;" << '\n'; + indent(f_enum) << "}" << '\n' << '\n'; - indent(f_enum) << "/**" << endl; + indent(f_enum) << "/**" << '\n'; indent(f_enum) << " * Get the integer value of this enum value, as defined in the Thrift IDL." - << endl; - indent(f_enum) << " */" << endl; - indent(f_enum) << java_override_annotation() << endl; - indent(f_enum) << "public int getValue() {" << endl; - indent(f_enum) << " return value;" << endl; - indent(f_enum) << "}" << endl << endl; - - indent(f_enum) << "/**" << endl; + << '\n'; + indent(f_enum) << " */" << '\n'; + indent(f_enum) << java_override_annotation() << '\n'; + indent(f_enum) << "public int getValue() {" << '\n'; + indent(f_enum) << " return value;" << '\n'; + indent(f_enum) << "}" << '\n' << '\n'; + + indent(f_enum) << "/**" << '\n'; indent(f_enum) << " * Find a the enum type by its integer value, as defined in the Thrift IDL." - << endl; - indent(f_enum) << " * @return null if the value is not found." << endl; - indent(f_enum) << " */" << endl; - indent(f_enum) << java_nullable_annotation() << endl; - indent(f_enum) << "public static " + tenum->get_name() + " findByValue(int value) { " << endl; + << '\n'; + indent(f_enum) << " * @return null if the value is not found." << '\n'; + indent(f_enum) << " */" << '\n'; + indent(f_enum) << java_nullable_annotation() << '\n'; + indent(f_enum) << "public static " + tenum->get_name() + " findByValue(int value) { " << '\n'; indent_up(); - indent(f_enum) << "switch (value) {" << endl; + indent(f_enum) << "switch (value) {" << '\n'; indent_up(); for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) { int value = (*c_iter)->get_value(); - indent(f_enum) << "case " << value << ":" << endl; - indent(f_enum) << " return " << (*c_iter)->get_name() << ";" << endl; + indent(f_enum) << "case " << value << ":" << '\n'; + indent(f_enum) << " return " << (*c_iter)->get_name() << ";" << '\n'; } - indent(f_enum) << "default:" << endl; - indent(f_enum) << " return null;" << endl; + indent(f_enum) << "default:" << '\n'; + indent(f_enum) << " return null;" << '\n'; indent_down(); - indent(f_enum) << "}" << endl; + indent(f_enum) << "}" << '\n'; indent_down(); - indent(f_enum) << "}" << endl; + indent(f_enum) << "}" << '\n'; scope_down(f_enum); @@ -677,8 +674,8 @@ void t_java_generator::generate_consts(std::vector consts) { // Print header f_consts << autogen_comment() << java_package() << java_suppressions(); - f_consts << "public class " << make_valid_java_identifier(program_name_) << "Constants {" << endl - << endl; + f_consts << "public class " << make_valid_java_identifier(program_name_) << "Constants {" << '\n' + << '\n'; indent_up(); vector::iterator c_iter; for (c_iter = consts.begin(); c_iter != consts.end(); ++c_iter) { @@ -687,7 +684,7 @@ void t_java_generator::generate_consts(std::vector consts) { (*c_iter)->get_value(), false); } indent_down(); - indent(f_consts) << "}" << endl; + indent(f_consts) << "}" << '\n'; f_consts.close(); } @@ -710,9 +707,9 @@ void t_java_generator::print_const_value(std::ostream& out, } if (type->is_base_type()) { string v2 = render_const_value(out, type, value); - out << name << " = " << v2 << ";" << endl << endl; + out << name << " = " << v2 << ";" << '\n' << '\n'; } else if (type->is_enum()) { - out << name << " = " << render_const_value(out, type, value) << ";" << endl << endl; + out << name << " = " << render_const_value(out, type, value) << ";" << '\n' << '\n'; } else if (type->is_struct() || type->is_xception()) { const vector& unsorted_fields = ((t_struct*)type)->get_members(); vector fields = unsorted_fields; @@ -720,9 +717,9 @@ void t_java_generator::print_const_value(std::ostream& out, vector::const_iterator f_iter; const map& val = value->get_map(); map::const_iterator v_iter; - out << name << " = new " << type_name(type, false, true) << "();" << endl; + out << name << " = new " << type_name(type, false, true) << "();" << '\n'; if (!in_static) { - indent(out) << "static {" << endl; + indent(out) << "static {" << '\n'; indent_up(); } for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { @@ -738,22 +735,22 @@ void t_java_generator::print_const_value(std::ostream& out, string val = render_const_value(out, field_type, v_iter->second); indent(out) << name << "."; std::string cap_name = get_cap_name(v_iter->first->get_string()); - out << "set" << cap_name << "(" << val << ");" << endl; + out << "set" << cap_name << "(" << val << ");" << '\n'; } if (!in_static) { indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } - out << endl; + out << '\n'; } else if (type->is_map()) { std::string constructor_args; if (is_enum_map(type)) { constructor_args = inner_enum_type_name(type); } out << name << " = new " << type_name(type, false, true) << "(" << constructor_args << ");" - << endl; + << '\n'; if (!in_static) { - indent(out) << "static {" << endl; + indent(out) << "static {" << '\n'; indent_up(); } t_type* ktype = ((t_map*)type)->get_key_type(); @@ -763,22 +760,22 @@ void t_java_generator::print_const_value(std::ostream& out, for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { string key = render_const_value(out, ktype, v_iter->first); string val = render_const_value(out, vtype, v_iter->second); - indent(out) << name << ".put(" << key << ", " << val << ");" << endl; + indent(out) << name << ".put(" << key << ", " << val << ");" << '\n'; } if (!in_static) { indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } - out << endl; + out << '\n'; } else if (type->is_list() || type->is_set()) { if (is_enum_set(type)) { out << name << " = " << type_name(type, false, true, true) << ".noneOf(" - << inner_enum_type_name(type) << ");" << endl; + << inner_enum_type_name(type) << ");" << '\n'; } else { - out << name << " = new " << type_name(type, false, true) << "();" << endl; + out << name << " = new " << type_name(type, false, true) << "();" << '\n'; } if (!in_static) { - indent(out) << "static {" << endl; + indent(out) << "static {" << '\n'; indent_up(); } t_type* etype; @@ -791,13 +788,13 @@ void t_java_generator::print_const_value(std::ostream& out, vector::const_iterator v_iter; for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { string val = render_const_value(out, etype, *v_iter); - indent(out) << name << ".add(" << val << ");" << endl; + indent(out) << name << ".add(" << val << ");" << '\n'; } if (!in_static) { indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } - out << endl; + out << '\n'; } else { throw "compiler error: no const of type " + type->get_name(); } @@ -926,7 +923,7 @@ void t_java_generator::generate_java_union(t_struct* tstruct) { } if (is_deprecated) { - indent(f_struct) << "@Deprecated" << endl; + indent(f_struct) << "@Deprecated" << '\n'; } indent(f_struct) << "public " << (is_final ? "final " : "") << "class " << make_valid_java_identifier(tstruct->get_name()) << " extends org.apache.thrift.TUnion<" << make_valid_java_identifier(tstruct->get_name()) << ", " @@ -937,52 +934,52 @@ void t_java_generator::generate_java_union(t_struct* tstruct) { generate_struct_desc(f_struct, tstruct); generate_field_descs(f_struct, tstruct); - f_struct << endl; + f_struct << '\n'; generate_field_name_constants(f_struct, tstruct); - f_struct << endl; + f_struct << '\n'; generate_java_meta_data_map(f_struct, tstruct); generate_union_constructor(f_struct, tstruct); - f_struct << endl; + f_struct << '\n'; generate_union_abstract_methods(f_struct, tstruct); - f_struct << endl; + f_struct << '\n'; generate_java_struct_get_fields(f_struct); generate_java_struct_get_metadata(f_struct); generate_java_struct_field_by_id(f_struct, tstruct); - f_struct << endl; + f_struct << '\n'; generate_union_getters_and_setters(f_struct, tstruct); - f_struct << endl; + f_struct << '\n'; generate_union_is_set_methods(f_struct, tstruct); - f_struct << endl; + f_struct << '\n'; generate_union_comparisons(f_struct, tstruct); - f_struct << endl; + f_struct << '\n'; generate_union_hashcode(f_struct, tstruct); - f_struct << endl; + f_struct << '\n'; generate_java_struct_write_object(f_struct, tstruct); - f_struct << endl; + f_struct << '\n'; generate_java_struct_read_object(f_struct, tstruct); - f_struct << endl; + f_struct << '\n'; scope_down(f_struct); @@ -993,63 +990,63 @@ void t_java_generator::generate_union_constructor(ostream& out, t_struct* tstruc const vector& members = tstruct->get_members(); vector::const_iterator m_iter; - indent(out) << "public " << type_name(tstruct) << "() {" << endl; + indent(out) << "public " << type_name(tstruct) << "() {" << '\n'; indent_up(); bool default_value = false; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { t_type* type = get_true_type((*m_iter)->get_type()); if ((*m_iter)->get_value() != nullptr) { indent(out) << "super(_Fields." << constant_name((*m_iter)->get_name()) << ", " - << render_const_value(out, type, (*m_iter)->get_value()) << ");" << endl; + << render_const_value(out, type, (*m_iter)->get_value()) << ");" << '\n'; default_value = true; break; } } if (default_value == false) { - indent(out) << "super();" << endl; + indent(out) << "super();" << '\n'; } indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; indent(out) << "public " << type_name(tstruct) << "(_Fields setField, java.lang.Object value) {" - << endl; - indent(out) << " super(setField, value);" << endl; - indent(out) << "}" << endl << endl; + << '\n'; + indent(out) << " super(setField, value);" << '\n'; + indent(out) << "}" << '\n' << '\n'; indent(out) << "public " << type_name(tstruct) << "(" << type_name(tstruct) << " other) {" - << endl; - indent(out) << " super(other);" << endl; - indent(out) << "}" << endl; + << '\n'; + indent(out) << " super(other);" << '\n'; + indent(out) << "}" << '\n'; - indent(out) << java_override_annotation() << endl; - indent(out) << "public " << make_valid_java_identifier(tstruct->get_name()) << " deepCopy() {" << endl; - indent(out) << " return new " << tstruct->get_name() << "(this);" << endl; - indent(out) << "}" << endl << endl; + indent(out) << java_override_annotation() << '\n'; + indent(out) << "public " << make_valid_java_identifier(tstruct->get_name()) << " deepCopy() {" << '\n'; + indent(out) << " return new " << tstruct->get_name() << "(this);" << '\n'; + indent(out) << "}" << '\n' << '\n'; // generate "constructors" for each field for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { t_type* type = (*m_iter)->get_type(); indent(out) << "public static " << type_name(tstruct) << " " << (*m_iter)->get_name() << "(" - << type_name(type) << " value) {" << endl; - indent(out) << " " << type_name(tstruct) << " x = new " << type_name(tstruct) << "();" << endl; - indent(out) << " x.set" << get_cap_name((*m_iter)->get_name()) << "(value);" << endl; - indent(out) << " return x;" << endl; - indent(out) << "}" << endl << endl; + << type_name(type) << " value) {" << '\n'; + indent(out) << " " << type_name(tstruct) << " x = new " << type_name(tstruct) << "();" << '\n'; + indent(out) << " x.set" << get_cap_name((*m_iter)->get_name()) << "(value);" << '\n'; + indent(out) << " return x;" << '\n'; + indent(out) << "}" << '\n' << '\n'; if (type->is_binary()) { indent(out) << "public static " << type_name(tstruct) << " " << (*m_iter)->get_name() - << "(byte[] value) {" << endl; + << "(byte[] value) {" << '\n'; indent(out) << " " << type_name(tstruct) << " x = new " << type_name(tstruct) << "();" - << endl; + << '\n'; indent(out) << " x.set" << get_cap_name((*m_iter)->get_name()); if (unsafe_binaries_) { - indent(out) << "(java.nio.ByteBuffer.wrap(value));" << endl; + indent(out) << "(java.nio.ByteBuffer.wrap(value));" << '\n'; } else { - indent(out) << "(java.nio.ByteBuffer.wrap(value.clone()));" << endl; + indent(out) << "(java.nio.ByteBuffer.wrap(value.clone()));" << '\n'; } - indent(out) << " return x;" << endl; - indent(out) << "}" << endl << endl; + indent(out) << " return x;" << '\n'; + indent(out) << "}" << '\n' << '\n'; } } } @@ -1063,7 +1060,7 @@ void t_java_generator::generate_union_getters_and_setters(ostream& out, t_struct if (first) { first = false; } else { - out << endl; + out << '\n'; } t_field* field = (*m_iter); @@ -1074,95 +1071,95 @@ void t_java_generator::generate_union_getters_and_setters(ostream& out, t_struct generate_java_doc(out, field); if (type->is_binary()) { if (is_deprecated) { - indent(out) << "@Deprecated" << endl; + indent(out) << "@Deprecated" << '\n'; } - indent(out) << "public byte[] get" << cap_name << "() {" << endl; + indent(out) << "public byte[] get" << cap_name << "() {" << '\n'; indent(out) << " set" << cap_name << "(org.apache.thrift.TBaseHelper.rightSize(buffer" - << get_cap_name("for") << cap_name << "()));" << endl; + << get_cap_name("for") << cap_name << "()));" << '\n'; indent(out) << " java.nio.ByteBuffer b = buffer" << get_cap_name("for") << cap_name << "();" - << endl; - indent(out) << " return b == null ? null : b.array();" << endl; - indent(out) << "}" << endl; + << '\n'; + indent(out) << " return b == null ? null : b.array();" << '\n'; + indent(out) << "}" << '\n'; - out << endl; + out << '\n'; indent(out) << "public java.nio.ByteBuffer buffer" << get_cap_name("for") - << get_cap_name(field->get_name()) << "() {" << endl; + << get_cap_name(field->get_name()) << "() {" << '\n'; indent(out) << " if (getSetField() == _Fields." << constant_name(field->get_name()) << ") {" - << endl; + << '\n'; if (unsafe_binaries_) { - indent(out) << " return (java.nio.ByteBuffer)getFieldValue();" << endl; + indent(out) << " return (java.nio.ByteBuffer)getFieldValue();" << '\n'; } else { indent(out) << " return " "org.apache.thrift.TBaseHelper.copyBinary((java.nio.ByteBuffer)getFieldValue());" - << endl; + << '\n'; } - indent(out) << " } else {" << endl; + indent(out) << " } else {" << '\n'; indent(out) << " throw new java.lang.RuntimeException(\"Cannot get field '" << field->get_name() << "' because union is currently set to \" + getFieldDesc(getSetField()).name);" - << endl; - indent(out) << " }" << endl; - indent(out) << "}" << endl; + << '\n'; + indent(out) << " }" << '\n'; + indent(out) << "}" << '\n'; } else { if (is_deprecated) { - indent(out) << "@Deprecated" << endl; + indent(out) << "@Deprecated" << '\n'; } indent(out) << "public " << type_name(field->get_type()) << " get" - << get_cap_name(field->get_name()) << "() {" << endl; + << get_cap_name(field->get_name()) << "() {" << '\n'; indent(out) << " if (getSetField() == _Fields." << constant_name(field->get_name()) << ") {" - << endl; + << '\n'; indent(out) << " return (" << type_name(field->get_type(), true) << ")getFieldValue();" - << endl; - indent(out) << " } else {" << endl; + << '\n'; + indent(out) << " } else {" << '\n'; indent(out) << " throw new java.lang.RuntimeException(\"Cannot get field '" << field->get_name() << "' because union is currently set to \" + getFieldDesc(getSetField()).name);" - << endl; - indent(out) << " }" << endl; - indent(out) << "}" << endl; + << '\n'; + indent(out) << " }" << '\n'; + indent(out) << "}" << '\n'; } - out << endl; + out << '\n'; generate_java_doc(out, field); if (type->is_binary()) { if (is_deprecated) { - indent(out) << "@Deprecated" << endl; + indent(out) << "@Deprecated" << '\n'; } indent(out) << "public void set" << get_cap_name(field->get_name()) << "(byte[] value) {" - << endl; + << '\n'; indent(out) << " set" << get_cap_name(field->get_name()); if (unsafe_binaries_) { - indent(out) << "(java.nio.ByteBuffer.wrap(value));" << endl; + indent(out) << "(java.nio.ByteBuffer.wrap(value));" << '\n'; } else { - indent(out) << "(java.nio.ByteBuffer.wrap(value.clone()));" << endl; + indent(out) << "(java.nio.ByteBuffer.wrap(value.clone()));" << '\n'; } - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; - out << endl; + out << '\n'; } if (is_deprecated) { - indent(out) << "@Deprecated" << endl; + indent(out) << "@Deprecated" << '\n'; } indent(out) << "public void set" << get_cap_name(field->get_name()) << "(" - << type_name(field->get_type()) << " value) {" << endl; + << type_name(field->get_type()) << " value) {" << '\n'; - indent(out) << " setField_ = _Fields." << constant_name(field->get_name()) << ";" << endl; + indent(out) << " setField_ = _Fields." << constant_name(field->get_name()) << ";" << '\n'; if (type_can_be_null(field->get_type())) { indent(out) << " value_ = java.util.Objects.requireNonNull(value,\"" - << "_Fields." << constant_name(field->get_name()) << "\");" << endl; + << "_Fields." << constant_name(field->get_name()) << "\");" << '\n'; } else { - indent(out) << " value_ = value;" << endl; + indent(out) << " value_ = value;" << '\n'; } - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } } @@ -1175,49 +1172,49 @@ void t_java_generator::generate_union_is_set_methods(ostream& out, t_struct* tst if (first) { first = false; } else { - out << endl; + out << '\n'; } std::string field_name = (*m_iter)->get_name(); indent(out) << "public boolean is" << get_cap_name("set") << get_cap_name(field_name) << "() {" - << endl; + << '\n'; indent_up(); - indent(out) << "return setField_ == _Fields." << constant_name(field_name) << ";" << endl; + indent(out) << "return setField_ == _Fields." << constant_name(field_name) << ";" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } } void t_java_generator::generate_union_abstract_methods(ostream& out, t_struct* tstruct) { generate_check_type(out, tstruct); - out << endl; + out << '\n'; generate_standard_scheme_read_value(out, tstruct); - out << endl; + out << '\n'; generate_standard_scheme_write_value(out, tstruct); - out << endl; + out << '\n'; generate_tuple_scheme_read_value(out, tstruct); - out << endl; + out << '\n'; generate_tuple_scheme_write_value(out, tstruct); - out << endl; + out << '\n'; generate_get_field_desc(out, tstruct); - out << endl; + out << '\n'; generate_get_struct_desc(out, tstruct); - out << endl; - indent(out) << java_override_annotation() << endl; - indent(out) << "protected _Fields enumForId(short id) {" << endl; - indent(out) << " return _Fields.findByThriftIdOrThrow(id);" << endl; - indent(out) << "}" << endl; + out << '\n'; + indent(out) << java_override_annotation() << '\n'; + indent(out) << "protected _Fields enumForId(short id) {" << '\n'; + indent(out) << " return _Fields.findByThriftIdOrThrow(id);" << '\n'; + indent(out) << "}" << '\n'; } void t_java_generator::generate_check_type(ostream& out, t_struct* tstruct) { - indent(out) << java_override_annotation() << endl; + indent(out) << java_override_annotation() << '\n'; indent(out) << "protected void checkType(_Fields setField, java.lang.Object value) throws " "java.lang.ClassCastException {" - << endl; + << '\n'; indent_up(); - indent(out) << "switch (setField) {" << endl; + indent(out) << "switch (setField) {" << '\n'; indent_up(); const vector& members = tstruct->get_members(); @@ -1226,42 +1223,42 @@ void t_java_generator::generate_check_type(ostream& out, t_struct* tstruct) { for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { t_field* field = (*m_iter); - indent(out) << "case " << constant_name(field->get_name()) << ":" << endl; + indent(out) << "case " << constant_name(field->get_name()) << ":" << '\n'; indent(out) << " if (value instanceof " << type_name(field->get_type(), true, false, true) - << ") {" << endl; - indent(out) << " break;" << endl; - indent(out) << " }" << endl; + << ") {" << '\n'; + indent(out) << " break;" << '\n'; + indent(out) << " }" << '\n'; indent(out) << " throw new java.lang.ClassCastException(\"Was expecting value of type " << type_name(field->get_type(), true, false) << " for field '" << field->get_name() - << "', but got \" + value.getClass().getSimpleName());" << endl; + << "', but got \" + value.getClass().getSimpleName());" << '\n'; // do the real check here } - indent(out) << "default:" << endl; + indent(out) << "default:" << '\n'; indent(out) << " throw new java.lang.IllegalArgumentException(\"Unknown field id \" + setField);" - << endl; + << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } void t_java_generator::generate_standard_scheme_read_value(ostream& out, t_struct* tstruct) { - indent(out) << java_override_annotation() << endl; + indent(out) << java_override_annotation() << '\n'; indent(out) << "protected java.lang.Object standardSchemeReadValue(org.apache.thrift.protocol.TProtocol " "iprot, org.apache.thrift.protocol.TField field) throws " "org.apache.thrift.TException {" - << endl; + << '\n'; indent_up(); - indent(out) << "_Fields setField = _Fields.findByThriftId(field.id);" << endl; - indent(out) << "if (setField != null) {" << endl; + indent(out) << "_Fields setField = _Fields.findByThriftId(field.id);" << '\n'; + indent(out) << "if (setField != null) {" << '\n'; indent_up(); - indent(out) << "switch (setField) {" << endl; + indent(out) << "switch (setField) {" << '\n'; indent_up(); const vector& members = tstruct->get_members(); @@ -1270,53 +1267,53 @@ void t_java_generator::generate_standard_scheme_read_value(ostream& out, t_struc for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { t_field* field = (*m_iter); - indent(out) << "case " << constant_name(field->get_name()) << ":" << endl; + indent(out) << "case " << constant_name(field->get_name()) << ":" << '\n'; indent_up(); indent(out) << "if (field.type == " << constant_name(field->get_name()) << "_FIELD_DESC.type) {" - << endl; + << '\n'; indent_up(); indent(out) << type_name(field->get_type(), true, false) << " " << field->get_name() << ";" - << endl; + << '\n'; generate_deserialize_field(out, field, ""); - indent(out) << "return " << field->get_name() << ";" << endl; + indent(out) << "return " << field->get_name() << ";" << '\n'; indent_down(); - indent(out) << "} else {" << endl; - indent(out) << " org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);" << endl; - indent(out) << " return null;" << endl; - indent(out) << "}" << endl; + indent(out) << "} else {" << '\n'; + indent(out) << " org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);" << '\n'; + indent(out) << " return null;" << '\n'; + indent(out) << "}" << '\n'; indent_down(); } - indent(out) << "default:" << endl; + indent(out) << "default:" << '\n'; indent(out) << " throw new java.lang.IllegalStateException(\"setField wasn't null, but didn't match any " "of the case statements!\");" - << endl; + << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; indent_down(); - indent(out) << "} else {" << endl; + indent(out) << "} else {" << '\n'; indent_up(); - indent(out) << "org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);" << endl; - indent(out) << "return null;" << endl; + indent(out) << "org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);" << '\n'; + indent(out) << "return null;" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } void t_java_generator::generate_standard_scheme_write_value(ostream& out, t_struct* tstruct) { - indent(out) << java_override_annotation() << endl; + indent(out) << java_override_annotation() << '\n'; indent(out) << "protected void standardSchemeWriteValue(org.apache.thrift.protocol.TProtocol " "oprot) throws org.apache.thrift.TException {" - << endl; + << '\n'; indent_up(); - indent(out) << "switch (setField_) {" << endl; + indent(out) << "switch (setField_) {" << '\n'; indent_up(); const vector& members = tstruct->get_members(); @@ -1325,42 +1322,42 @@ void t_java_generator::generate_standard_scheme_write_value(ostream& out, t_stru for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { t_field* field = (*m_iter); - indent(out) << "case " << constant_name(field->get_name()) << ":" << endl; + indent(out) << "case " << constant_name(field->get_name()) << ":" << '\n'; indent_up(); indent(out) << type_name(field->get_type(), true, false) << " " << field->get_name() << " = (" - << type_name(field->get_type(), true, false) << ")value_;" << endl; + << type_name(field->get_type(), true, false) << ")value_;" << '\n'; generate_serialize_field(out, field); - indent(out) << "return;" << endl; + indent(out) << "return;" << '\n'; indent_down(); } - indent(out) << "default:" << endl; + indent(out) << "default:" << '\n'; indent(out) << " throw new java.lang.IllegalStateException(\"Cannot write union with unknown field \" + " "setField_);" - << endl; + << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } void t_java_generator::generate_tuple_scheme_read_value(ostream& out, t_struct* tstruct) { - indent(out) << java_override_annotation() << endl; + indent(out) << java_override_annotation() << '\n'; indent(out) << "protected java.lang.Object tupleSchemeReadValue(org.apache.thrift.protocol.TProtocol " "iprot, short fieldID) throws org.apache.thrift.TException {" - << endl; + << '\n'; indent_up(); - indent(out) << "_Fields setField = _Fields.findByThriftId(fieldID);" << endl; - indent(out) << "if (setField != null) {" << endl; + indent(out) << "_Fields setField = _Fields.findByThriftId(fieldID);" << '\n'; + indent(out) << "if (setField != null) {" << '\n'; indent_up(); - indent(out) << "switch (setField) {" << endl; + indent(out) << "switch (setField) {" << '\n'; indent_up(); const vector& members = tstruct->get_members(); @@ -1369,45 +1366,45 @@ void t_java_generator::generate_tuple_scheme_read_value(ostream& out, t_struct* for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { t_field* field = (*m_iter); - indent(out) << "case " << constant_name(field->get_name()) << ":" << endl; + indent(out) << "case " << constant_name(field->get_name()) << ":" << '\n'; indent_up(); indent(out) << type_name(field->get_type(), true, false) << " " << field->get_name() << ";" - << endl; + << '\n'; generate_deserialize_field(out, field, ""); - indent(out) << "return " << field->get_name() << ";" << endl; + indent(out) << "return " << field->get_name() << ";" << '\n'; indent_down(); } - indent(out) << "default:" << endl; + indent(out) << "default:" << '\n'; indent(out) << " throw new java.lang.IllegalStateException(\"setField wasn't null, but didn't match any " "of the case statements!\");" - << endl; + << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; indent_down(); - indent(out) << "} else {" << endl; + indent(out) << "} else {" << '\n'; indent_up(); indent(out) << "throw new org.apache.thrift.protocol.TProtocolException(\"Couldn't find a field " "with field id \" + fieldID);" - << endl; + << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } void t_java_generator::generate_tuple_scheme_write_value(ostream& out, t_struct* tstruct) { - indent(out) << java_override_annotation() << endl; + indent(out) << java_override_annotation() << '\n'; indent(out) << "protected void tupleSchemeWriteValue(org.apache.thrift.protocol.TProtocol oprot) " "throws org.apache.thrift.TException {" - << endl; + << '\n'; indent_up(); - indent(out) << "switch (setField_) {" << endl; + indent(out) << "switch (setField_) {" << '\n'; indent_up(); const vector& members = tstruct->get_members(); @@ -1416,119 +1413,119 @@ void t_java_generator::generate_tuple_scheme_write_value(ostream& out, t_struct* for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { t_field* field = (*m_iter); - indent(out) << "case " << constant_name(field->get_name()) << ":" << endl; + indent(out) << "case " << constant_name(field->get_name()) << ":" << '\n'; indent_up(); indent(out) << type_name(field->get_type(), true, false) << " " << field->get_name() << " = (" - << type_name(field->get_type(), true, false) << ")value_;" << endl; + << type_name(field->get_type(), true, false) << ")value_;" << '\n'; generate_serialize_field(out, field); - indent(out) << "return;" << endl; + indent(out) << "return;" << '\n'; indent_down(); } - indent(out) << "default:" << endl; + indent(out) << "default:" << '\n'; indent(out) << " throw new java.lang.IllegalStateException(\"Cannot write union with unknown field \" + " "setField_);" - << endl; + << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } void t_java_generator::generate_get_field_desc(ostream& out, t_struct* tstruct) { - indent(out) << java_override_annotation() << endl; + indent(out) << java_override_annotation() << '\n'; indent(out) << "protected org.apache.thrift.protocol.TField getFieldDesc(_Fields setField) {" - << endl; + << '\n'; indent_up(); const vector& members = tstruct->get_members(); vector::const_iterator m_iter; - indent(out) << "switch (setField) {" << endl; + indent(out) << "switch (setField) {" << '\n'; indent_up(); for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { t_field* field = (*m_iter); - indent(out) << "case " << constant_name(field->get_name()) << ":" << endl; - indent(out) << " return " << constant_name(field->get_name()) << "_FIELD_DESC;" << endl; + indent(out) << "case " << constant_name(field->get_name()) << ":" << '\n'; + indent(out) << " return " << constant_name(field->get_name()) << "_FIELD_DESC;" << '\n'; } - indent(out) << "default:" << endl; + indent(out) << "default:" << '\n'; indent(out) << " throw new java.lang.IllegalArgumentException(\"Unknown field id \" + setField);" - << endl; + << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } void t_java_generator::generate_get_struct_desc(ostream& out, t_struct* tstruct) { (void)tstruct; - indent(out) << java_override_annotation() << endl; - indent(out) << "protected org.apache.thrift.protocol.TStruct getStructDesc() {" << endl; - indent(out) << " return STRUCT_DESC;" << endl; - indent(out) << "}" << endl; + indent(out) << java_override_annotation() << '\n'; + indent(out) << "protected org.apache.thrift.protocol.TStruct getStructDesc() {" << '\n'; + indent(out) << " return STRUCT_DESC;" << '\n'; + indent(out) << "}" << '\n'; } void t_java_generator::generate_union_comparisons(ostream& out, t_struct* tstruct) { // equality - indent(out) << "public boolean equals(java.lang.Object other) {" << endl; - indent(out) << " if (other instanceof " << make_valid_java_identifier(tstruct->get_name()) << ") {" << endl; - indent(out) << " return equals((" << make_valid_java_identifier(tstruct->get_name()) << ")other);" << endl; - indent(out) << " } else {" << endl; - indent(out) << " return false;" << endl; - indent(out) << " }" << endl; - indent(out) << "}" << endl; + indent(out) << "public boolean equals(java.lang.Object other) {" << '\n'; + indent(out) << " if (other instanceof " << make_valid_java_identifier(tstruct->get_name()) << ") {" << '\n'; + indent(out) << " return equals((" << make_valid_java_identifier(tstruct->get_name()) << ")other);" << '\n'; + indent(out) << " } else {" << '\n'; + indent(out) << " return false;" << '\n'; + indent(out) << " }" << '\n'; + indent(out) << "}" << '\n'; - out << endl; + out << '\n'; - indent(out) << "public boolean equals(" << make_valid_java_identifier(tstruct->get_name()) << " other) {" << endl; + indent(out) << "public boolean equals(" << make_valid_java_identifier(tstruct->get_name()) << " other) {" << '\n'; indent(out) << " return other != null && getSetField() == other.getSetField() && " "getFieldValue().equals(other.getFieldValue());" - << endl; - indent(out) << "}" << endl; - out << endl; + << '\n'; + indent(out) << "}" << '\n'; + out << '\n'; - indent(out) << java_override_annotation() << endl; - indent(out) << "public int compareTo(" << type_name(tstruct) << " other) {" << endl; + indent(out) << java_override_annotation() << '\n'; + indent(out) << "public int compareTo(" << type_name(tstruct) << " other) {" << '\n'; indent(out) << " int lastComparison = org.apache.thrift.TBaseHelper.compareTo(getSetField(), " "other.getSetField());" - << endl; - indent(out) << " if (lastComparison == 0) {" << endl; + << '\n'; + indent(out) << " if (lastComparison == 0) {" << '\n'; indent(out) << " return org.apache.thrift.TBaseHelper.compareTo(getFieldValue(), " "other.getFieldValue());" - << endl; - indent(out) << " }" << endl; - indent(out) << " return lastComparison;" << endl; - indent(out) << "}" << endl; - out << endl; + << '\n'; + indent(out) << " }" << '\n'; + indent(out) << " return lastComparison;" << '\n'; + indent(out) << "}" << '\n'; + out << '\n'; } void t_java_generator::generate_union_hashcode(ostream& out, t_struct* tstruct) { (void)tstruct; - indent(out) << java_override_annotation() << endl; - indent(out) << "public int hashCode() {" << endl; + indent(out) << java_override_annotation() << '\n'; + indent(out) << "public int hashCode() {" << '\n'; indent(out) << " java.util.List list = new java.util.ArrayList();" - << endl; - indent(out) << " list.add(this.getClass().getName());" << endl; - indent(out) << " org.apache.thrift.TFieldIdEnum setField = getSetField();" << endl; - indent(out) << " if (setField != null) {" << endl; - indent(out) << " list.add(setField.getThriftFieldId());" << endl; - indent(out) << " java.lang.Object value = getFieldValue();" << endl; - indent(out) << " if (value instanceof org.apache.thrift.TEnum) {" << endl; - indent(out) << " list.add(((org.apache.thrift.TEnum)getFieldValue()).getValue());" << endl; - indent(out) << " } else {" << endl; - indent(out) << " list.add(value);" << endl; - indent(out) << " }" << endl; - indent(out) << " }" << endl; - indent(out) << " return list.hashCode();" << endl; + << '\n'; + indent(out) << " list.add(this.getClass().getName());" << '\n'; + indent(out) << " org.apache.thrift.TFieldIdEnum setField = getSetField();" << '\n'; + indent(out) << " if (setField != null) {" << '\n'; + indent(out) << " list.add(setField.getThriftFieldId());" << '\n'; + indent(out) << " java.lang.Object value = getFieldValue();" << '\n'; + indent(out) << " if (value instanceof org.apache.thrift.TEnum) {" << '\n'; + indent(out) << " list.add(((org.apache.thrift.TEnum)getFieldValue()).getValue());" << '\n'; + indent(out) << " } else {" << '\n'; + indent(out) << " list.add(value);" << '\n'; + indent(out) << " }" << '\n'; + indent(out) << " }" << '\n'; + indent(out) << " return list.hashCode();" << '\n'; indent(out) << "}"; } @@ -1558,7 +1555,7 @@ void t_java_generator::generate_java_struct_definition(ostream& out, } if (is_deprecated) { - indent(out) << "@Deprecated" << endl; + indent(out) << "@Deprecated" << '\n'; } indent(out) << "public " << (is_final ? "final " : "") << (in_class ? "static " : "") << "class " << make_valid_java_identifier(tstruct->get_name()) << " "; @@ -1584,15 +1581,15 @@ void t_java_generator::generate_java_struct_definition(ostream& out, const vector& members = tstruct->get_members(); vector::const_iterator m_iter; - out << endl; + out << '\n'; generate_field_descs(out, tstruct); - out << endl; + out << '\n'; generate_scheme_map(out, tstruct); - out << endl; + out << '\n'; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { if (bean_style_ || private_members_) { @@ -1601,10 +1598,10 @@ void t_java_generator::generate_java_struct_definition(ostream& out, generate_java_doc(out, *m_iter); indent(out) << "public "; } - out << declare_field(*m_iter, false, true) << endl; + out << declare_field(*m_iter, false, true) << '\n'; } - out << endl; + out << '\n'; if (android_style_) { generate_java_struct_parcelable(out, tstruct); @@ -1614,9 +1611,9 @@ void t_java_generator::generate_java_struct_definition(ostream& out, // isset data if (members.size() > 0) { - out << endl; + out << '\n'; - indent(out) << "// isset id assignments" << endl; + indent(out) << "// isset id assignments" << '\n'; int i = 0; int optionals = 0; @@ -1626,7 +1623,7 @@ void t_java_generator::generate_java_struct_definition(ostream& out, } if (!type_can_be_null((*m_iter)->get_type())) { indent(out) << "private static final int " << isset_field_id(*m_iter) << " = " << i << ";" - << endl; + << '\n'; i++; } } @@ -1636,22 +1633,22 @@ void t_java_generator::generate_java_struct_definition(ostream& out, case ISSET_NONE: break; case ISSET_PRIMITIVE: - indent(out) << "private " << primitiveType << " __isset_bitfield = 0;" << endl; + indent(out) << "private " << primitiveType << " __isset_bitfield = 0;" << '\n'; break; case ISSET_BITSET: indent(out) << "private java.util.BitSet __isset_bit_vector = new java.util.BitSet(" << i - << ");" << endl; + << ");" << '\n'; break; } if (optionals > 0) { - std::string output_string = "private static final _Fields optionals[] = {"; + std::string output_string = "private static final _Fields[] optionals = {"; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { if ((*m_iter)->get_req() == t_field::T_OPTIONAL) { output_string = output_string + "_Fields." + constant_name((*m_iter)->get_name()) + ","; } } - indent(out) << output_string.substr(0, output_string.length() - 1) << "};" << endl; + indent(out) << output_string.substr(0, output_string.length() - 1) << "};" << '\n'; } } @@ -1660,7 +1657,7 @@ void t_java_generator::generate_java_struct_definition(ostream& out, bool all_optional_members = true; // Default constructor - indent(out) << "public " << make_valid_java_identifier(tstruct->get_name()) << "() {" << endl; + indent(out) << "public " << make_valid_java_identifier(tstruct->get_name()) << "() {" << '\n'; indent_up(); for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { t_type* t = get_true_type((*m_iter)->get_type()); @@ -1673,27 +1670,27 @@ void t_java_generator::generate_java_struct_definition(ostream& out, } } indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; if (!members.empty() && !all_optional_members) { // Full constructor for all fields - indent(out) << "public " << make_valid_java_identifier(tstruct->get_name()) << "(" << endl; + indent(out) << "public " << make_valid_java_identifier(tstruct->get_name()) << "(" << '\n'; indent_up(); bool first = true; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { if ((*m_iter)->get_req() != t_field::T_OPTIONAL) { if (!first) { - out << "," << endl; + out << "," << '\n'; } first = false; indent(out) << type_name((*m_iter)->get_type()) << " " << make_valid_java_identifier((*m_iter)->get_name()); } } - out << ")" << endl; + out << ")" << '\n'; indent_down(); - indent(out) << "{" << endl; + indent(out) << "{" << '\n'; indent_up(); - indent(out) << "this();" << endl; + indent(out) << "this();" << '\n'; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { if ((*m_iter)->get_req() != t_field::T_OPTIONAL) { t_type* type = get_true_type((*m_iter)->get_type()); @@ -1701,44 +1698,44 @@ void t_java_generator::generate_java_struct_definition(ostream& out, if (unsafe_binaries_) { indent(out) << "this." << make_valid_java_identifier((*m_iter)->get_name()) << " = " << make_valid_java_identifier((*m_iter)->get_name()) << ";" - << endl; + << '\n'; } else { indent(out) << "this." << make_valid_java_identifier((*m_iter)->get_name()) << " = org.apache.thrift.TBaseHelper.copyBinary(" << make_valid_java_identifier((*m_iter)->get_name()) - << ");" << endl; + << ");" << '\n'; } } else { indent(out) << "this." << make_valid_java_identifier((*m_iter)->get_name()) << " = " << make_valid_java_identifier((*m_iter)->get_name()) << ";" - << endl; + << '\n'; } generate_isset_set(out, (*m_iter), ""); } } indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } // copy constructor - indent(out) << "/**" << endl; - indent(out) << " * Performs a deep copy on other." << endl; - indent(out) << " */" << endl; + indent(out) << "/**" << '\n'; + indent(out) << " * Performs a deep copy on other." << '\n'; + indent(out) << " */" << '\n'; indent(out) << "public " << make_valid_java_identifier(tstruct->get_name()) << "(" << make_valid_java_identifier(tstruct->get_name()) << " other) {" - << endl; + << '\n'; indent_up(); switch (needs_isset(tstruct)) { case ISSET_NONE: break; case ISSET_PRIMITIVE: - indent(out) << "__isset_bitfield = other.__isset_bitfield;" << endl; + indent(out) << "__isset_bitfield = other.__isset_bitfield;" << '\n'; break; case ISSET_BITSET: - indent(out) << "__isset_bit_vector.clear();" << endl; - indent(out) << "__isset_bit_vector.or(other.__isset_bit_vector);" << endl; + indent(out) << "__isset_bit_vector.clear();" << '\n'; + indent(out) << "__isset_bit_vector.or(other.__isset_bit_vector);" << '\n'; break; } @@ -1749,33 +1746,33 @@ void t_java_generator::generate_java_struct_definition(ostream& out, bool can_be_null = type_can_be_null(type); if (can_be_null) { - indent(out) << "if (other." << generate_isset_check(field) << ") {" << endl; + indent(out) << "if (other." << generate_isset_check(field) << ") {" << '\n'; indent_up(); } if (type->is_container()) { generate_deep_copy_container(out, "other", field_name, "__this__" + field_name, type); - indent(out) << "this." << make_valid_java_identifier(field_name) << " = __this__" << field_name << ";" << endl; + indent(out) << "this." << make_valid_java_identifier(field_name) << " = __this__" << field_name << ";" << '\n'; } else { indent(out) << "this." << make_valid_java_identifier(field_name) << " = "; generate_deep_copy_non_container(out, "other." + make_valid_java_identifier(field_name), field_name, type); - out << ";" << endl; + out << ";" << '\n'; } if (can_be_null) { indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } } indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; // clone method, so that you can deep copy an object when you don't know its class. - indent(out) << java_override_annotation() << endl; - indent(out) << "public " << make_valid_java_identifier(tstruct->get_name()) << " deepCopy() {" << endl; - indent(out) << " return new " << make_valid_java_identifier(tstruct->get_name()) << "(this);" << endl; - indent(out) << "}" << endl << endl; + indent(out) << java_override_annotation() << '\n'; + indent(out) << "public " << make_valid_java_identifier(tstruct->get_name()) << " deepCopy() {" << '\n'; + indent(out) << " return new " << make_valid_java_identifier(tstruct->get_name()) << "(this);" << '\n'; + indent(out) << "}" << '\n' << '\n'; generate_java_struct_clear(out, tstruct); @@ -1806,7 +1803,7 @@ void t_java_generator::generate_java_struct_definition(ostream& out, generate_java_scheme_lookup(out); scope_down(out); - out << endl; + out << '\n'; } /** @@ -1818,30 +1815,30 @@ void t_java_generator::generate_java_struct_parcelable(ostream& out, t_struct* t const vector& members = tstruct->get_members(); vector::const_iterator m_iter; - out << indent() << java_override_annotation() << endl - << indent() << "public void writeToParcel(android.os.Parcel out, int flags) {" << endl; + out << indent() << java_override_annotation() << '\n' + << indent() << "public void writeToParcel(android.os.Parcel out, int flags) {" << '\n'; indent_up(); string bitsetPrimitiveType = ""; switch (needs_isset(tstruct, &bitsetPrimitiveType)) { case ISSET_NONE: break; case ISSET_PRIMITIVE: - indent(out) << "//primitive bitfield of type: " << bitsetPrimitiveType << endl; + indent(out) << "//primitive bitfield of type: " << bitsetPrimitiveType << '\n'; if (bitsetPrimitiveType == "byte") { - indent(out) << "out.writeByte(__isset_bitfield);" << endl; + indent(out) << "out.writeByte(__isset_bitfield);" << '\n'; } else if (bitsetPrimitiveType == "short") { - indent(out) << "out.writeInt(new Short(__isset_bitfield).intValue());" << endl; + indent(out) << "out.writeInt(new Short(__isset_bitfield).intValue());" << '\n'; } else if (bitsetPrimitiveType == "int") { - indent(out) << "out.writeInt(__isset_bitfield);" << endl; + indent(out) << "out.writeInt(__isset_bitfield);" << '\n'; } else if (bitsetPrimitiveType == "long") { - indent(out) << "out.writeLong(__isset_bitfield);" << endl; + indent(out) << "out.writeLong(__isset_bitfield);" << '\n'; } - out << endl; + out << '\n'; break; case ISSET_BITSET: - indent(out) << "//BitSet" << endl; - indent(out) << "out.writeSerializable(__isset_bit_vector);" << endl; - out << endl; + indent(out) << "//BitSet" << '\n'; + indent(out) << "out.writeSerializable(__isset_bit_vector);" << '\n'; + out << '\n'; break; } for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { @@ -1849,54 +1846,54 @@ void t_java_generator::generate_java_struct_parcelable(ostream& out, t_struct* t string name = (*m_iter)->get_name(); if (t->is_struct()) { - indent(out) << "out.writeParcelable(" << name << ", flags);" << endl; + indent(out) << "out.writeParcelable(" << name << ", flags);" << '\n'; } else if (type_name(t) == "float") { - indent(out) << "out.writeFloat(" << name << ");" << endl; + indent(out) << "out.writeFloat(" << name << ");" << '\n'; } else if (t->is_enum()) { indent(out) << "out.writeInt(" << name << " != null ? " << name << ".getValue() : -1);" - << endl; + << '\n'; } else if (t->is_list()) { if (((t_list*)t)->get_elem_type()->get_true_type()->is_struct()) { - indent(out) << "out.writeTypedList(" << name << ");" << endl; + indent(out) << "out.writeTypedList(" << name << ");" << '\n'; } else { - indent(out) << "out.writeList(" << name << ");" << endl; + indent(out) << "out.writeList(" << name << ");" << '\n'; } } else if (t->is_map()) { - indent(out) << "out.writeMap(" << name << ");" << endl; + indent(out) << "out.writeMap(" << name << ");" << '\n'; } else if (t->is_base_type()) { if (t->is_binary()) { - indent(out) << "out.writeInt(" << name << "!=null ? 1 : 0);" << endl; - indent(out) << "if(" << name << " != null) { " << endl; + indent(out) << "out.writeInt(" << name << "!=null ? 1 : 0);" << '\n'; + indent(out) << "if(" << name << " != null) { " << '\n'; indent_up(); indent(out) << "out.writeByteArray(" << name << ".array(), " << name << ".position() + " << name << ".arrayOffset(), " << name << ".limit() - " << name - << ".position() );" << endl; + << ".position() );" << '\n'; scope_down(out); } else { switch (((t_base_type*)t)->get_base()) { case t_base_type::TYPE_I16: - indent(out) << "out.writeInt(new Short(" << name << ").intValue());" << endl; + indent(out) << "out.writeInt(new Short(" << name << ").intValue());" << '\n'; break; case t_base_type::TYPE_UUID: - indent(out) << "out.writeUuid(" << name << ");" << endl; + indent(out) << "out.writeUuid(" << name << ");" << '\n'; break; case t_base_type::TYPE_I32: - indent(out) << "out.writeInt(" << name << ");" << endl; + indent(out) << "out.writeInt(" << name << ");" << '\n'; break; case t_base_type::TYPE_I64: - indent(out) << "out.writeLong(" << name << ");" << endl; + indent(out) << "out.writeLong(" << name << ");" << '\n'; break; case t_base_type::TYPE_BOOL: - indent(out) << "out.writeInt(" << name << " ? 1 : 0);" << endl; + indent(out) << "out.writeInt(" << name << " ? 1 : 0);" << '\n'; break; case t_base_type::TYPE_I8: - indent(out) << "out.writeByte(" << name << ");" << endl; + indent(out) << "out.writeByte(" << name << ");" << '\n'; break; case t_base_type::TYPE_DOUBLE: - indent(out) << "out.writeDouble(" << name << ");" << endl; + indent(out) << "out.writeDouble(" << name << ");" << '\n'; break; case t_base_type::TYPE_STRING: - indent(out) << "out.writeString(" << name << ");" << endl; + indent(out) << "out.writeString(" << name << ");" << '\n'; break; case t_base_type::TYPE_VOID: break; @@ -1907,38 +1904,38 @@ void t_java_generator::generate_java_struct_parcelable(ostream& out, t_struct* t } } scope_down(out); - out << endl; + out << '\n'; - out << indent() << java_override_annotation() << endl - << indent() << "public int describeContents() {" << endl; + out << indent() << java_override_annotation() << '\n' + << indent() << "public int describeContents() {" << '\n'; indent_up(); - out << indent() << "return 0;" << endl; + out << indent() << "return 0;" << '\n'; scope_down(out); - out << endl; + out << '\n'; - indent(out) << "public " << tname << "(android.os.Parcel in) {" << endl; + indent(out) << "public " << tname << "(android.os.Parcel in) {" << '\n'; indent_up(); // read in the required bitfield switch (needs_isset(tstruct, &bitsetPrimitiveType)) { case ISSET_NONE: break; case ISSET_PRIMITIVE: - indent(out) << "//primitive bitfield of type: " << bitsetPrimitiveType << endl; + indent(out) << "//primitive bitfield of type: " << bitsetPrimitiveType << '\n'; if (bitsetPrimitiveType == "byte") { - indent(out) << "__isset_bitfield = in.readByte();" << endl; + indent(out) << "__isset_bitfield = in.readByte();" << '\n'; } else if (bitsetPrimitiveType == "short") { - indent(out) << "__isset_bitfield = (short) in.readInt();" << endl; + indent(out) << "__isset_bitfield = (short) in.readInt();" << '\n'; } else if (bitsetPrimitiveType == "int") { - indent(out) << "__isset_bitfield = in.readInt();" << endl; + indent(out) << "__isset_bitfield = in.readInt();" << '\n'; } else if (bitsetPrimitiveType == "long") { - indent(out) << "__isset_bitfield = in.readLong();" << endl; + indent(out) << "__isset_bitfield = in.readLong();" << '\n'; } - out << endl; + out << '\n'; break; case ISSET_BITSET: - indent(out) << "//BitSet" << endl; - indent(out) << "__isset_bit_vector = (java.util.BitSet) in.readSerializable();" << endl; - out << endl; + indent(out) << "//BitSet" << '\n'; + indent(out) << "__isset_bit_vector = (java.util.BitSet) in.readSerializable();" << '\n'; + out << '\n'; break; } // read all the fields @@ -1949,57 +1946,57 @@ void t_java_generator::generate_java_struct_parcelable(ostream& out, t_struct* t if (t->is_struct()) { indent(out) << prefix << "= in.readParcelable(" << tname << ".class.getClassLoader());" - << endl; + << '\n'; } else if (t->is_enum()) { - indent(out) << prefix << " = " << type_name(t) << ".findByValue(in.readInt());" << endl; + indent(out) << prefix << " = " << type_name(t) << ".findByValue(in.readInt());" << '\n'; } else if (t->is_list()) { t_list* list = (t_list*)t; - indent(out) << prefix << " = new " << type_name(t, false, true) << "();" << endl; + indent(out) << prefix << " = new " << type_name(t, false, true) << "();" << '\n'; if (list->get_elem_type()->get_true_type()->is_struct()) { indent(out) << "in.readTypedList(" << prefix << ", " << type_name(list->get_elem_type()) - << ".CREATOR);" << endl; + << ".CREATOR);" << '\n'; } else { indent(out) << "in.readList(" << prefix << ", " << tname << ".class.getClassLoader());" - << endl; + << '\n'; } } else if (t->is_map()) { - indent(out) << prefix << " = new " << type_name(t, false, true) << "();" << endl; + indent(out) << prefix << " = new " << type_name(t, false, true) << "();" << '\n'; indent(out) << " in.readMap(" << prefix << ", " << tname << ".class.getClassLoader());" - << endl; + << '\n'; } else if (type_name(t) == "float") { - indent(out) << prefix << " = in.readFloat();" << endl; + indent(out) << prefix << " = in.readFloat();" << '\n'; } else if (t->is_base_type()) { t_base_type* bt = (t_base_type*)t; if (bt->is_binary()) { - indent(out) << "if(in.readInt()==1) {" << endl; + indent(out) << "if(in.readInt()==1) {" << '\n'; indent_up(); - indent(out) << prefix << " = java.nio.ByteBuffer.wrap(in.createByteArray());" << endl; + indent(out) << prefix << " = java.nio.ByteBuffer.wrap(in.createByteArray());" << '\n'; scope_down(out); } else { switch (bt->get_base()) { case t_base_type::TYPE_I8: - indent(out) << prefix << " = in.readByte();" << endl; + indent(out) << prefix << " = in.readByte();" << '\n'; break; case t_base_type::TYPE_I16: - indent(out) << prefix << " = (short) in.readInt();" << endl; + indent(out) << prefix << " = (short) in.readInt();" << '\n'; break; case t_base_type::TYPE_I32: - indent(out) << prefix << " = in.readInt();" << endl; + indent(out) << prefix << " = in.readInt();" << '\n'; break; case t_base_type::TYPE_I64: - indent(out) << prefix << " = in.readLong();" << endl; + indent(out) << prefix << " = in.readLong();" << '\n'; break; case t_base_type::TYPE_UUID: - indent(out) << prefix << " = in.readUuid();" << endl; + indent(out) << prefix << " = in.readUuid();" << '\n'; break; case t_base_type::TYPE_BOOL: - indent(out) << prefix << " = (in.readInt()==1);" << endl; + indent(out) << prefix << " = (in.readInt()==1);" << '\n'; break; case t_base_type::TYPE_DOUBLE: - indent(out) << prefix << " = in.readDouble();" << endl; + indent(out) << prefix << " = in.readDouble();" << '\n'; break; case t_base_type::TYPE_STRING: - indent(out) << prefix << "= in.readString();" << endl; + indent(out) << prefix << "= in.readString();" << '\n'; break; case t_base_type::TYPE_VOID: break; @@ -2011,29 +2008,29 @@ void t_java_generator::generate_java_struct_parcelable(ostream& out, t_struct* t } scope_down(out); - out << endl; + out << '\n'; indent(out) << "public static final android.os.Parcelable.Creator<" << tname - << "> CREATOR = new android.os.Parcelable.Creator<" << tname << ">() {" << endl; + << "> CREATOR = new android.os.Parcelable.Creator<" << tname << ">() {" << '\n'; indent_up(); - indent(out) << java_override_annotation() << endl - << indent() << "public " << tname << "[] newArray(int size) {" << endl; + indent(out) << java_override_annotation() << '\n' + << indent() << "public " << tname << "[] newArray(int size) {" << '\n'; indent_up(); - indent(out) << "return new " << tname << "[size];" << endl; + indent(out) << "return new " << tname << "[size];" << '\n'; scope_down(out); - out << endl; + out << '\n'; - indent(out) << java_override_annotation() << endl + indent(out) << java_override_annotation() << '\n' << indent() << "public " << tname << " createFromParcel(android.os.Parcel in) {" - << endl; + << '\n'; indent_up(); - indent(out) << "return new " << tname << "(in);" << endl; + indent(out) << "return new " << tname << "(in);" << '\n'; scope_down(out); indent_down(); - indent(out) << "};" << endl; - out << endl; + indent(out) << "};" << '\n'; + out << '\n'; } /** @@ -2042,26 +2039,26 @@ void t_java_generator::generate_java_struct_parcelable(ostream& out, t_struct* t * @param tstruct The struct definition */ void t_java_generator::generate_java_struct_equality(ostream& out, t_struct* tstruct) { - out << indent() << java_override_annotation() << endl - << indent() << "public boolean equals(java.lang.Object that) {" << endl; + out << indent() << java_override_annotation() << '\n' + << indent() << "public boolean equals(java.lang.Object that) {" << '\n'; indent_up(); - out << indent() << "if (that instanceof " << make_valid_java_identifier(tstruct->get_name()) << ")" << endl - << indent() << " return this.equals((" << make_valid_java_identifier(tstruct->get_name()) << ")that);" << endl - << indent() << "return false;" << endl; + out << indent() << "if (that instanceof " << make_valid_java_identifier(tstruct->get_name()) << ")" << '\n' + << indent() << " return this.equals((" << make_valid_java_identifier(tstruct->get_name()) << ")that);" << '\n' + << indent() << "return false;" << '\n'; scope_down(out); - out << endl; + out << '\n'; - out << indent() << "public boolean equals(" << make_valid_java_identifier(tstruct->get_name()) << " that) {" << endl; + out << indent() << "public boolean equals(" << make_valid_java_identifier(tstruct->get_name()) << " that) {" << '\n'; indent_up(); - out << indent() << "if (that == null)" << endl - << indent() << " return false;" << endl - << indent() << "if (this == that)" << endl - << indent() << " return true;" << endl; + out << indent() << "if (that == null)" << '\n' + << indent() << " return false;" << '\n' + << indent() << "if (this == that)" << '\n' + << indent() << " return true;" << '\n'; const vector& members = tstruct->get_members(); vector::const_iterator m_iter; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { - out << endl; + out << '\n'; t_type* t = get_true_type((*m_iter)->get_type()); // Most existing Thrift code does not use isset or optional/required, @@ -2079,14 +2076,14 @@ void t_java_generator::generate_java_struct_equality(ostream& out, t_struct* tst that_present += " && that." + generate_isset_check(*m_iter); } - out << indent() << "boolean this_present_" << name << " = " << this_present << ";" << endl - << indent() << "boolean that_present_" << name << " = " << that_present << ";" << endl + out << indent() << "boolean this_present_" << name << " = " << this_present << ";" << '\n' + << indent() << "boolean that_present_" << name << " = " << that_present << ";" << '\n' << indent() << "if (" - << "this_present_" << name << " || that_present_" << name << ") {" << endl; + << "this_present_" << name << " || that_present_" << name << ") {" << '\n'; indent_up(); out << indent() << "if (!(" - << "this_present_" << name << " && that_present_" << name << "))" << endl - << indent() << " return false;" << endl; + << "this_present_" << name << " && that_present_" << name << "))" << '\n' + << indent() << " return false;" << '\n'; if (t->is_binary()) { unequal = "!this." + make_valid_java_identifier(name) + ".equals(that." + make_valid_java_identifier(name) + ")"; @@ -2096,25 +2093,25 @@ void t_java_generator::generate_java_struct_equality(ostream& out, t_struct* tst unequal = "this." + make_valid_java_identifier(name) + " != that." + make_valid_java_identifier(name); } - out << indent() << "if (" << unequal << ")" << endl << indent() << " return false;" << endl; + out << indent() << "if (" << unequal << ")" << '\n' << indent() << " return false;" << '\n'; scope_down(out); } - out << endl; - indent(out) << "return true;" << endl; + out << '\n'; + indent(out) << "return true;" << '\n'; scope_down(out); - out << endl; + out << '\n'; const int MUL = 8191; // HashCode multiplier const int B_YES = 131071; const int B_NO = 524287; - out << indent() << java_override_annotation() << endl - << indent() << "public int hashCode() {" << endl; + out << indent() << java_override_annotation() << '\n' + << indent() << "public int hashCode() {" << '\n'; indent_up(); - indent(out) << "int hashCode = 1;" << endl; + indent(out) << "int hashCode = 1;" << '\n'; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { - out << endl; + out << '\n'; t_type* t = get_true_type((*m_iter)->get_type()); bool is_optional = (*m_iter)->get_req() == t_field::T_OPTIONAL; @@ -2123,37 +2120,37 @@ void t_java_generator::generate_java_struct_equality(ostream& out, t_struct* tst if (is_optional || can_be_null) { indent(out) << "hashCode = hashCode * " << MUL << " + ((" << generate_isset_check(*m_iter) - << ") ? " << B_YES << " : " << B_NO << ");" << endl; + << ") ? " << B_YES << " : " << B_NO << ");" << '\n'; } if (is_optional || can_be_null) { - indent(out) << "if (" + generate_isset_check(*m_iter) + ")" << endl; + indent(out) << "if (" + generate_isset_check(*m_iter) + ")" << '\n'; indent_up(); } if (t->is_enum()) { - indent(out) << "hashCode = hashCode * " << MUL << " + " << name << ".getValue();" << endl; + indent(out) << "hashCode = hashCode * " << MUL << " + " << name << ".getValue();" << '\n'; } else if (t->is_base_type()) { switch (((t_base_type*)t)->get_base()) { case t_base_type::TYPE_STRING: case t_base_type::TYPE_UUID: - indent(out) << "hashCode = hashCode * " << MUL << " + " << name << ".hashCode();" << endl; + indent(out) << "hashCode = hashCode * " << MUL << " + " << name << ".hashCode();" << '\n'; break; case t_base_type::TYPE_BOOL: indent(out) << "hashCode = hashCode * " << MUL << " + ((" << name << ") ? " << B_YES - << " : " << B_NO << ");" << endl; + << " : " << B_NO << ");" << '\n'; break; case t_base_type::TYPE_I8: - indent(out) << "hashCode = hashCode * " << MUL << " + (int) (" << name << ");" << endl; + indent(out) << "hashCode = hashCode * " << MUL << " + (int) (" << name << ");" << '\n'; break; case t_base_type::TYPE_I16: case t_base_type::TYPE_I32: - indent(out) << "hashCode = hashCode * " << MUL << " + " << name << ";" << endl; + indent(out) << "hashCode = hashCode * " << MUL << " + " << name << ";" << '\n'; break; case t_base_type::TYPE_I64: case t_base_type::TYPE_DOUBLE: indent(out) << "hashCode = hashCode * " << MUL - << " + org.apache.thrift.TBaseHelper.hashCode(" << name << ");" << endl; + << " + org.apache.thrift.TBaseHelper.hashCode(" << name << ");" << '\n'; break; case t_base_type::TYPE_VOID: throw std::logic_error("compiler error: a struct field cannot be void"); @@ -2162,7 +2159,7 @@ void t_java_generator::generate_java_struct_equality(ostream& out, t_struct* tst + t_base_type::t_base_name(((t_base_type*)t)->get_base())); } } else { - indent(out) << "hashCode = hashCode * " << MUL << " + " << name << ".hashCode();" << endl; + indent(out) << "hashCode = hashCode * " << MUL << " + " << name << ".hashCode();" << '\n'; } if (is_optional || can_be_null) { @@ -2170,49 +2167,49 @@ void t_java_generator::generate_java_struct_equality(ostream& out, t_struct* tst } } - out << endl; - indent(out) << "return hashCode;" << endl; + out << '\n'; + indent(out) << "return hashCode;" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } void t_java_generator::generate_java_struct_compare_to(ostream& out, t_struct* tstruct) { - indent(out) << java_override_annotation() << endl; - indent(out) << "public int compareTo(" << type_name(tstruct) << " other) {" << endl; + indent(out) << java_override_annotation() << '\n'; + indent(out) << "public int compareTo(" << type_name(tstruct) << " other) {" << '\n'; indent_up(); - indent(out) << "if (!getClass().equals(other.getClass())) {" << endl; - indent(out) << " return getClass().getName().compareTo(other.getClass().getName());" << endl; - indent(out) << "}" << endl; - out << endl; + indent(out) << "if (!getClass().equals(other.getClass())) {" << '\n'; + indent(out) << " return getClass().getName().compareTo(other.getClass().getName());" << '\n'; + indent(out) << "}" << '\n'; + out << '\n'; - indent(out) << "int lastComparison = 0;" << endl; - out << endl; + indent(out) << "int lastComparison = 0;" << '\n'; + out << '\n'; const vector& members = tstruct->get_members(); vector::const_iterator m_iter; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { t_field* field = *m_iter; indent(out) << "lastComparison = java.lang.Boolean.compare(" << generate_isset_check(field) - << ", other." << generate_isset_check(field) << ");" << endl; - indent(out) << "if (lastComparison != 0) {" << endl; - indent(out) << " return lastComparison;" << endl; - indent(out) << "}" << endl; + << ", other." << generate_isset_check(field) << ");" << '\n'; + indent(out) << "if (lastComparison != 0) {" << '\n'; + indent(out) << " return lastComparison;" << '\n'; + indent(out) << "}" << '\n'; - indent(out) << "if (" << generate_isset_check(field) << ") {" << endl; + indent(out) << "if (" << generate_isset_check(field) << ") {" << '\n'; indent(out) << " lastComparison = org.apache.thrift.TBaseHelper.compareTo(this." << make_valid_java_identifier(field->get_name()) - << ", other." << make_valid_java_identifier(field->get_name()) << ");" << endl; - indent(out) << " if (lastComparison != 0) {" << endl; - indent(out) << " return lastComparison;" << endl; - indent(out) << " }" << endl; - indent(out) << "}" << endl; + << ", other." << make_valid_java_identifier(field->get_name()) << ");" << '\n'; + indent(out) << " if (lastComparison != 0) {" << '\n'; + indent(out) << " return lastComparison;" << '\n'; + indent(out) << " }" << '\n'; + indent(out) << "}" << '\n'; } - indent(out) << "return 0;" << endl; + indent(out) << "return 0;" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } /** @@ -2221,63 +2218,63 @@ void t_java_generator::generate_java_struct_compare_to(ostream& out, t_struct* t * @param tstruct The struct definition */ void t_java_generator::generate_java_struct_reader(ostream& out, t_struct* /*tstruct*/) { - indent(out) << java_override_annotation() << endl; + indent(out) << java_override_annotation() << '\n'; indent(out) << "public void read(org.apache.thrift.protocol.TProtocol iprot) throws " "org.apache.thrift.TException {" - << endl; + << '\n'; indent_up(); - indent(out) << "scheme(iprot).read(iprot, this);" << endl; + indent(out) << "scheme(iprot).read(iprot, this);" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } // generates java method to perform various checks // (e.g. check that all required fields are set) void t_java_generator::generate_java_validator(ostream& out, t_struct* tstruct) { - indent(out) << "public void validate() throws org.apache.thrift.TException {" << endl; + indent(out) << "public void validate() throws org.apache.thrift.TException {" << '\n'; indent_up(); const vector& fields = tstruct->get_members(); vector::const_iterator f_iter; - out << indent() << "// check for required fields" << endl; + out << indent() << "// check for required fields" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if ((*f_iter)->get_req() == t_field::T_REQUIRED) { if (bean_style_) { - out << indent() << "if (!" << generate_isset_check(*f_iter) << ") {" << endl + out << indent() << "if (!" << generate_isset_check(*f_iter) << ") {" << '\n' << indent() << " throw new org.apache.thrift.protocol.TProtocolException(\"Required field '" - << (*f_iter)->get_name() << "' is unset! Struct:\" + toString());" << endl - << indent() << "}" << endl - << endl; + << (*f_iter)->get_name() << "' is unset! Struct:\" + toString());" << '\n' + << indent() << "}" << '\n' + << '\n'; } else { if (type_can_be_null((*f_iter)->get_type())) { - indent(out) << "if (" << (*f_iter)->get_name() << " == null) {" << endl; + indent(out) << "if (" << (*f_iter)->get_name() << " == null) {" << '\n'; indent(out) << " throw new org.apache.thrift.protocol.TProtocolException(\"Required field '" - << (*f_iter)->get_name() << "' was not present! Struct: \" + toString());" << endl; - indent(out) << "}" << endl; + << (*f_iter)->get_name() << "' was not present! Struct: \" + toString());" << '\n'; + indent(out) << "}" << '\n'; } else { indent(out) << "// alas, we cannot check '" << (*f_iter)->get_name() << "' because it's a primitive and you chose the non-beans generator." - << endl; + << '\n'; } } } } - out << indent() << "// check for sub-struct validity" << endl; + out << indent() << "// check for sub-struct validity" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { t_type* type = get_true_type((*f_iter)->get_type()); if (type->is_struct() && !((t_struct*)type)->is_union()) { - out << indent() << "if (" << make_valid_java_identifier((*f_iter)->get_name()) << " != null) {" << endl; - out << indent() << " " << make_valid_java_identifier((*f_iter)->get_name()) << ".validate();" << endl; - out << indent() << "}" << endl; + out << indent() << "if (" << make_valid_java_identifier((*f_iter)->get_name()) << " != null) {" << '\n'; + out << indent() << " " << make_valid_java_identifier((*f_iter)->get_name()) << ".validate();" << '\n'; + out << indent() << "}" << '\n'; } } indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } /** @@ -2286,15 +2283,15 @@ void t_java_generator::generate_java_validator(ostream& out, t_struct* tstruct) * @param tstruct The struct definition */ void t_java_generator::generate_java_struct_writer(ostream& out, t_struct* /*tstruct*/) { - indent(out) << java_override_annotation() << endl; + indent(out) << java_override_annotation() << '\n'; indent(out) << "public void write(org.apache.thrift.protocol.TProtocol oprot) throws " "org.apache.thrift.TException {" - << endl; + << '\n'; indent_up(); - indent(out) << "scheme(oprot).write(oprot, this);" << endl; + indent(out) << "scheme(oprot).write(oprot, this);" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } /** @@ -2309,21 +2306,21 @@ void t_java_generator::generate_java_struct_result_writer(ostream& out, t_struct (void)tstruct; indent(out) << "public void write(org.apache.thrift.protocol.TProtocol oprot) throws " "org.apache.thrift.TException {" - << endl; + << '\n'; indent_up(); - indent(out) << "scheme(oprot).write(oprot, this);" << endl; + indent(out) << "scheme(oprot).write(oprot, this);" << '\n'; indent_down(); - indent(out) << " }" << endl << endl; + indent(out) << " }" << '\n' << '\n'; } void t_java_generator::generate_java_struct_field_by_id(ostream& out, t_struct* tstruct) { (void)tstruct; - indent(out) << java_nullable_annotation() << endl; - indent(out) << java_override_annotation() << endl; - indent(out) << "public _Fields fieldForId(int fieldId) {" << endl; - indent(out) << " return _Fields.findByThriftId(fieldId);" << endl; - indent(out) << "}" << endl << endl; + indent(out) << java_nullable_annotation() << '\n'; + indent(out) << java_override_annotation() << '\n'; + indent(out) << "public _Fields fieldForId(int fieldId) {" << '\n'; + indent(out) << " return _Fields.findByThriftId(fieldId);" << '\n'; + indent(out) << "}" << '\n' << '\n'; } void t_java_generator::generate_java_struct_get_fields(ostream& out) { @@ -2342,9 +2339,9 @@ void t_java_generator::generate_reflection_getters(ostringstream& out, t_type* type, string field_name, string cap_name) { - indent(out) << "case " << constant_name(field_name) << ":" << endl; + indent(out) << "case " << constant_name(field_name) << ":" << '\n'; indent_up(); - indent(out) << "return " << (type->is_bool() ? "is" : "get") << cap_name << "();" << endl << endl; + indent(out) << "return " << (type->is_bool() ? "is" : "get") << cap_name << "();" << '\n' << '\n'; indent_down(); } @@ -2353,24 +2350,24 @@ void t_java_generator::generate_reflection_setters(ostringstream& out, string field_name, string cap_name) { const bool is_binary = type->is_binary(); - indent(out) << "case " << constant_name(field_name) << ":" << endl; + indent(out) << "case " << constant_name(field_name) << ":" << '\n'; indent_up(); - indent(out) << "if (value == null) {" << endl; - indent(out) << " unset" << get_cap_name(field_name) << "();" << endl; - indent(out) << "} else {" << endl; + indent(out) << "if (value == null) {" << '\n'; + indent(out) << " unset" << get_cap_name(field_name) << "();" << '\n'; + indent(out) << "} else {" << '\n'; if (is_binary) { indent_up(); - indent(out) << "if (value instanceof byte[]) {" << endl; - indent(out) << " set" << cap_name << "((byte[])value);" << endl; - indent(out) << "} else {" << endl; + indent(out) << "if (value instanceof byte[]) {" << '\n'; + indent(out) << " set" << cap_name << "((byte[])value);" << '\n'; + indent(out) << "} else {" << '\n'; } - indent(out) << " set" << cap_name << "((" << type_name(type, true, false) << ")value);" << endl; + indent(out) << " set" << cap_name << "((" << type_name(type, true, false) << ")value);" << '\n'; if (is_binary) { - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; indent_down(); } - indent(out) << "}" << endl; - indent(out) << "break;" << endl << endl; + indent(out) << "}" << '\n'; + indent(out) << "break;" << '\n' << '\n'; indent_down(); } @@ -2397,25 +2394,25 @@ void t_java_generator::generate_generic_field_getters_setters(std::ostream& out, // create the setter - indent(out) << java_override_annotation() << endl; + indent(out) << java_override_annotation() << '\n'; indent(out) << "public void setFieldValue(_Fields field, " << java_nullable_annotation() - << " java.lang.Object value) {" << endl; - indent(out) << " switch (field) {" << endl; + << " java.lang.Object value) {" << '\n'; + indent(out) << " switch (field) {" << '\n'; out << setter_stream.str(); - indent(out) << " }" << endl; - indent(out) << "}" << endl << endl; + indent(out) << " }" << '\n'; + indent(out) << "}" << '\n' << '\n'; // create the getter - indent(out) << java_nullable_annotation() << endl; - indent(out) << java_override_annotation() << endl; - indent(out) << "public java.lang.Object getFieldValue(_Fields field) {" << endl; + indent(out) << java_nullable_annotation() << '\n'; + indent(out) << java_override_annotation() << '\n'; + indent(out) << "public java.lang.Object getFieldValue(_Fields field) {" << '\n'; indent_up(); - indent(out) << "switch (field) {" << endl; + indent(out) << "switch (field) {" << '\n'; out << getter_stream.str(); - indent(out) << "}" << endl; - indent(out) << "throw new java.lang.IllegalStateException();" << endl; + indent(out) << "}" << '\n'; + indent(out) << "throw new java.lang.IllegalStateException();" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } // Creates a generic isSet method that takes the field number as argument @@ -2426,28 +2423,28 @@ void t_java_generator::generate_generic_isset_method(std::ostream& out, t_struct // create the isSet method indent(out) << "/** Returns true if field corresponding to fieldID is set (has been assigned a " "value) and false otherwise */" - << endl; - indent(out) << java_override_annotation() << endl; - indent(out) << "public boolean isSet(_Fields field) {" << endl; + << '\n'; + indent(out) << java_override_annotation() << '\n'; + indent(out) << "public boolean isSet(_Fields field) {" << '\n'; indent_up(); - indent(out) << "if (field == null) {" << endl; - indent(out) << " throw new java.lang.IllegalArgumentException();" << endl; - indent(out) << "}" << endl << endl; + indent(out) << "if (field == null) {" << '\n'; + indent(out) << " throw new java.lang.IllegalArgumentException();" << '\n'; + indent(out) << "}" << '\n' << '\n'; - indent(out) << "switch (field) {" << endl; + indent(out) << "switch (field) {" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { t_field* field = *f_iter; - indent(out) << "case " << constant_name(field->get_name()) << ":" << endl; + indent(out) << "case " << constant_name(field->get_name()) << ":" << '\n'; indent_up(); - indent(out) << "return " << generate_isset_check(field) << ";" << endl; + indent(out) << "return " << generate_isset_check(field) << ";" << '\n'; indent_down(); } - indent(out) << "}" << endl; - indent(out) << "throw new java.lang.IllegalStateException();" << endl; + indent(out) << "}" << '\n'; + indent(out) << "throw new java.lang.IllegalStateException();" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } /** @@ -2472,7 +2469,7 @@ void t_java_generator::generate_java_bean_boilerplate(ostream& out, t_struct* ts // Method to return the size of the collection if (optional) { if (is_deprecated) { - indent(out) << "@Deprecated" << endl; + indent(out) << "@Deprecated" << '\n'; } if (use_jdk8_option_type_) { @@ -2481,20 +2478,20 @@ void t_java_generator::generate_java_bean_boilerplate(ostream& out, t_struct* ts indent(out) << "public " << thrift_option_class << " get" << cap_name; } - out << get_cap_name("size() {") << endl; + out << get_cap_name("size() {") << '\n'; indent_up(); - indent(out) << "if (this." << field_name << " == null) {" << endl; + indent(out) << "if (this." << field_name << " == null) {" << '\n'; indent_up(); if (use_jdk8_option_type_) { - indent(out) << "return " << jdk_option_class << ".empty();" << endl; + indent(out) << "return " << jdk_option_class << ".empty();" << '\n'; } else { - indent(out) << "return " << thrift_option_class << ".none();" << endl; + indent(out) << "return " << thrift_option_class << ".none();" << '\n'; } indent_down(); - indent(out) << "} else {" << endl; + indent(out) << "} else {" << '\n'; indent_up(); if (use_jdk8_option_type_) { @@ -2502,24 +2499,24 @@ void t_java_generator::generate_java_bean_boilerplate(ostream& out, t_struct* ts } else { indent(out) << "return " << thrift_option_class << ".some(this."; } - out << field_name << ".size());" << endl; + out << field_name << ".size());" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } else { if (is_deprecated) { - indent(out) << "@Deprecated" << endl; + indent(out) << "@Deprecated" << '\n'; } indent(out) << "public int get" << cap_name; - out << get_cap_name("size() {") << endl; + out << get_cap_name("size() {") << '\n'; indent_up(); indent(out) << "return (this." << field_name << " == null) ? 0 : " - << "this." << field_name << ".size();" << endl; + << "this." << field_name << ".size();" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } } @@ -2534,7 +2531,7 @@ void t_java_generator::generate_java_bean_boilerplate(ostream& out, t_struct* ts // Iterator getter for sets and lists if (optional) { if (is_deprecated) { - indent(out) << "@Deprecated" << endl; + indent(out) << "@Deprecated" << '\n'; } if (use_jdk8_option_type_) { @@ -2545,20 +2542,20 @@ void t_java_generator::generate_java_bean_boilerplate(ostream& out, t_struct* ts out << "java.util.Iterator<" << type_name(element_type, true, false) << ">> get" << cap_name; - out << get_cap_name("iterator() {") << endl; + out << get_cap_name("iterator() {") << '\n'; indent_up(); - indent(out) << "if (this." << field_name << " == null) {" << endl; + indent(out) << "if (this." << field_name << " == null) {" << '\n'; indent_up(); if (use_jdk8_option_type_) { - indent(out) << "return " << jdk_option_class << ".empty();" << endl; + indent(out) << "return " << jdk_option_class << ".empty();" << '\n'; } else { - indent(out) << "return " << thrift_option_class << ".none();" << endl; + indent(out) << "return " << thrift_option_class << ".none();" << '\n'; } indent_down(); - indent(out) << "} else {" << endl; + indent(out) << "} else {" << '\n'; indent_up(); if (use_jdk8_option_type_) { @@ -2566,104 +2563,104 @@ void t_java_generator::generate_java_bean_boilerplate(ostream& out, t_struct* ts } else { indent(out) << "return " << thrift_option_class << ".some(this."; } - out << field_name << ".iterator());" << endl; + out << field_name << ".iterator());" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } else { if (is_deprecated) { - indent(out) << "@Deprecated" << endl; + indent(out) << "@Deprecated" << '\n'; } - indent(out) << java_nullable_annotation() << endl; + indent(out) << java_nullable_annotation() << '\n'; indent(out) << "public java.util.Iterator<" << type_name(element_type, true, false) << "> get" << cap_name; - out << get_cap_name("iterator() {") << endl; + out << get_cap_name("iterator() {") << '\n'; indent_up(); indent(out) << "return (this." << field_name << " == null) ? null : " - << "this." << field_name << ".iterator();" << endl; + << "this." << field_name << ".iterator();" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } // Add to set or list, create if the set/list is null if (is_deprecated) { - indent(out) << "@Deprecated" << endl; + indent(out) << "@Deprecated" << '\n'; } indent(out) << "public void add" << get_cap_name("to"); - out << cap_name << "(" << type_name(element_type) << " elem) {" << endl; + out << cap_name << "(" << type_name(element_type) << " elem) {" << '\n'; indent_up(); - indent(out) << "if (this." << field_name << " == null) {" << endl; + indent(out) << "if (this." << field_name << " == null) {" << '\n'; indent_up(); indent(out) << "this." << field_name; if (is_enum_set(type)) { out << " = " << type_name(type, false, true, true) << ".noneOf(" - << inner_enum_type_name(type) << ");" << endl; + << inner_enum_type_name(type) << ");" << '\n'; } else { - out << " = new " << type_name(type, false, true) << "();" << endl; + out << " = new " << type_name(type, false, true) << "();" << '\n'; } indent_down(); - indent(out) << "}" << endl; - indent(out) << "this." << field_name << ".add(elem);" << endl; + indent(out) << "}" << '\n'; + indent(out) << "this." << field_name << ".add(elem);" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } else if (type->is_map()) { // Put to map t_type* key_type = ((t_map*)type)->get_key_type(); t_type* val_type = ((t_map*)type)->get_val_type(); if (is_deprecated) { - indent(out) << "@Deprecated" << endl; + indent(out) << "@Deprecated" << '\n'; } indent(out) << "public void put" << get_cap_name("to"); out << cap_name << "(" << type_name(key_type) << " key, " << type_name(val_type) << " val) {" - << endl; + << '\n'; indent_up(); - indent(out) << "if (this." << field_name << " == null) {" << endl; + indent(out) << "if (this." << field_name << " == null) {" << '\n'; indent_up(); std::string constructor_args; if (is_enum_map(type)) { constructor_args = inner_enum_type_name(type); } indent(out) << "this." << field_name << " = new " << type_name(type, false, true) << "(" - << constructor_args << ");" << endl; + << constructor_args << ");" << '\n'; indent_down(); - indent(out) << "}" << endl; - indent(out) << "this." << field_name << ".put(key, val);" << endl; + indent(out) << "}" << '\n'; + indent(out) << "this." << field_name << ".put(key, val);" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } // Simple getter generate_java_doc(out, field); if (type->is_binary()) { if (is_deprecated) { - indent(out) << "@Deprecated" << endl; + indent(out) << "@Deprecated" << '\n'; } - indent(out) << "public byte[] get" << cap_name << "() {" << endl; + indent(out) << "public byte[] get" << cap_name << "() {" << '\n'; indent(out) << " set" << cap_name << "(org.apache.thrift.TBaseHelper.rightSize(" - << field_name << "));" << endl; + << field_name << "));" << '\n'; indent(out) << " return " << field_name << " == null ? null : " << field_name << ".array();" - << endl; - indent(out) << "}" << endl << endl; + << '\n'; + indent(out) << "}" << '\n' << '\n'; indent(out) << "public java.nio.ByteBuffer buffer" << get_cap_name("for") << cap_name - << "() {" << endl; + << "() {" << '\n'; if (unsafe_binaries_) { - indent(out) << " return " << field_name << ";" << endl; + indent(out) << " return " << field_name << ";" << '\n'; } else { indent(out) << " return org.apache.thrift.TBaseHelper.copyBinary(" << field_name << ");" - << endl; + << '\n'; } - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } else { if (optional) { if (is_deprecated) { - indent(out) << "@Deprecated" << endl; + indent(out) << "@Deprecated" << '\n'; } if (use_jdk8_option_type_) { @@ -2677,10 +2674,10 @@ void t_java_generator::generate_java_bean_boilerplate(ostream& out, t_struct* ts } else { out << " get"; } - out << cap_name << "() {" << endl; + out << cap_name << "() {" << '\n'; indent_up(); - indent(out) << "if (this.isSet" << cap_name << "()) {" << endl; + indent(out) << "if (this.isSet" << cap_name << "()) {" << '\n'; indent_up(); if (use_jdk8_option_type_) { @@ -2688,28 +2685,28 @@ void t_java_generator::generate_java_bean_boilerplate(ostream& out, t_struct* ts } else { indent(out) << "return " << thrift_option_class << ".some(this."; } - out << field_name << ");" << endl; + out << field_name << ");" << '\n'; indent_down(); - indent(out) << "} else {" << endl; + indent(out) << "} else {" << '\n'; indent_up(); if (use_jdk8_option_type_) { - indent(out) << "return " << jdk_option_class << ".empty();" << endl; + indent(out) << "return " << jdk_option_class << ".empty();" << '\n'; } else { - indent(out) << "return " << thrift_option_class << ".none();" << endl; + indent(out) << "return " << thrift_option_class << ".none();" << '\n'; } indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } else { if (is_deprecated) { - indent(out) << "@Deprecated" << endl; + indent(out) << "@Deprecated" << '\n'; } if (type_can_be_null(type)) { - indent(out) << java_nullable_annotation() << endl; + indent(out) << java_nullable_annotation() << '\n'; } indent(out) << "public " << type_name(type); if (type->is_base_type() && ((t_base_type*)type)->get_base() == t_base_type::TYPE_BOOL) { @@ -2717,11 +2714,11 @@ void t_java_generator::generate_java_bean_boilerplate(ostream& out, t_struct* ts } else { out << " get"; } - out << cap_name << "() {" << endl; + out << cap_name << "() {" << '\n'; indent_up(); - indent(out) << "return this." << make_valid_java_identifier(field_name) << ";" << endl; + indent(out) << "return this." << make_valid_java_identifier(field_name) << ";" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } } @@ -2729,7 +2726,7 @@ void t_java_generator::generate_java_bean_boilerplate(ostream& out, t_struct* ts generate_java_doc(out, field); if (type->is_binary()) { if (is_deprecated) { - indent(out) << "@Deprecated" << endl; + indent(out) << "@Deprecated" << '\n'; } indent(out) << "public "; if (bean_style_) { @@ -2737,23 +2734,23 @@ void t_java_generator::generate_java_bean_boilerplate(ostream& out, t_struct* ts } else { out << type_name(tstruct); } - out << " set" << cap_name << "(byte[] " << make_valid_java_identifier(field_name) << ") {" << endl; + out << " set" << cap_name << "(byte[] " << make_valid_java_identifier(field_name) << ") {" << '\n'; indent(out) << " this." << make_valid_java_identifier(field_name) << " = " << make_valid_java_identifier(field_name) << " == null ? (java.nio.ByteBuffer)null"; if (unsafe_binaries_) { - indent(out) << " : java.nio.ByteBuffer.wrap(" << make_valid_java_identifier(field_name) << ");" << endl; + indent(out) << " : java.nio.ByteBuffer.wrap(" << make_valid_java_identifier(field_name) << ");" << '\n'; } else { - indent(out) << " : java.nio.ByteBuffer.wrap(" << make_valid_java_identifier(field_name) << ".clone());" << endl; + indent(out) << " : java.nio.ByteBuffer.wrap(" << make_valid_java_identifier(field_name) << ".clone());" << '\n'; } if (!bean_style_) { - indent(out) << " return this;" << endl; + indent(out) << " return this;" << '\n'; } - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } if (is_deprecated) { - indent(out) << "@Deprecated" << endl; + indent(out) << "@Deprecated" << '\n'; } indent(out) << "public "; if (bean_style_) { @@ -2764,7 +2761,7 @@ void t_java_generator::generate_java_bean_boilerplate(ostream& out, t_struct* ts out << " set" << cap_name << "(" << (type_can_be_null(type) ? (java_nullable_annotation() + " ") : "") << type_name(type) - << " " << make_valid_java_identifier(field_name) << ") {" << endl; + << " " << make_valid_java_identifier(field_name) << ") {" << '\n'; indent_up(); indent(out) << "this." << make_valid_java_identifier(field_name) << " = "; if (type->is_binary() && !unsafe_binaries_) { @@ -2772,70 +2769,70 @@ void t_java_generator::generate_java_bean_boilerplate(ostream& out, t_struct* ts } else { out << make_valid_java_identifier(field_name); } - out << ";" << endl; + out << ";" << '\n'; generate_isset_set(out, field, ""); if (!bean_style_) { - indent(out) << "return this;" << endl; + indent(out) << "return this;" << '\n'; } indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; // Unsetter if (is_deprecated) { - indent(out) << "@Deprecated" << endl; + indent(out) << "@Deprecated" << '\n'; } - indent(out) << "public void unset" << cap_name << "() {" << endl; + indent(out) << "public void unset" << cap_name << "() {" << '\n'; indent_up(); if (type_can_be_null(type)) { - indent(out) << "this." << make_valid_java_identifier(field_name) << " = null;" << endl; + indent(out) << "this." << make_valid_java_identifier(field_name) << " = null;" << '\n'; } else if (issetType == ISSET_PRIMITIVE) { indent(out) << "__isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, " - << isset_field_id(field) << ");" << endl; + << isset_field_id(field) << ");" << '\n'; } else { - indent(out) << "__isset_bit_vector.clear(" << isset_field_id(field) << ");" << endl; + indent(out) << "__isset_bit_vector.clear(" << isset_field_id(field) << ");" << '\n'; } indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; // isSet method indent(out) << "/** Returns true if field " << field_name - << " is set (has been assigned a value) and false otherwise */" << endl; + << " is set (has been assigned a value) and false otherwise */" << '\n'; if (is_deprecated) { - indent(out) << "@Deprecated" << endl; + indent(out) << "@Deprecated" << '\n'; } - indent(out) << "public boolean is" << get_cap_name("set") << cap_name << "() {" << endl; + indent(out) << "public boolean is" << get_cap_name("set") << cap_name << "() {" << '\n'; indent_up(); if (type_can_be_null(type)) { - indent(out) << "return this." << make_valid_java_identifier(field_name) << " != null;" << endl; + indent(out) << "return this." << make_valid_java_identifier(field_name) << " != null;" << '\n'; } else if (issetType == ISSET_PRIMITIVE) { indent(out) << "return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, " - << isset_field_id(field) << ");" << endl; + << isset_field_id(field) << ");" << '\n'; } else { - indent(out) << "return __isset_bit_vector.get(" << isset_field_id(field) << ");" << endl; + indent(out) << "return __isset_bit_vector.get(" << isset_field_id(field) << ");" << '\n'; } indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; if (is_deprecated) { - indent(out) << "@Deprecated" << endl; + indent(out) << "@Deprecated" << '\n'; } indent(out) << "public void set" << cap_name << get_cap_name("isSet") << "(boolean value) {" - << endl; + << '\n'; indent_up(); if (type_can_be_null(type)) { - indent(out) << "if (!value) {" << endl; - indent(out) << " this." << make_valid_java_identifier(field_name) << " = null;" << endl; - indent(out) << "}" << endl; + indent(out) << "if (!value) {" << '\n'; + indent(out) << " this." << make_valid_java_identifier(field_name) << " = null;" << '\n'; + indent(out) << "}" << '\n'; } else if (issetType == ISSET_PRIMITIVE) { indent(out) << "__isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, " - << isset_field_id(field) << ", value);" << endl; + << isset_field_id(field) << ", value);" << '\n'; } else { - indent(out) << "__isset_bit_vector.set(" << isset_field_id(field) << ", value);" << endl; + indent(out) << "__isset_bit_vector.set(" << isset_field_id(field) << ", value);" << '\n'; } indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } } @@ -2845,13 +2842,13 @@ void t_java_generator::generate_java_bean_boilerplate(ostream& out, t_struct* ts * @param tstruct The struct definition */ void t_java_generator::generate_java_struct_tostring(ostream& out, t_struct* tstruct) { - out << indent() << java_override_annotation() << endl - << indent() << "public java.lang.String toString() {" << endl; + out << indent() << java_override_annotation() << '\n' + << indent() << "public java.lang.String toString() {" << '\n'; indent_up(); out << indent() << "java.lang.StringBuilder sb = new java.lang.StringBuilder(\"" - << tstruct->get_name() << "(\");" << endl; - out << indent() << "boolean first = true;" << endl << endl; + << tstruct->get_name() << "(\");" << '\n'; + out << indent() << "boolean first = true;" << '\n' << '\n'; const vector& fields = tstruct->get_members(); vector::const_iterator f_iter; @@ -2859,55 +2856,55 @@ void t_java_generator::generate_java_struct_tostring(ostream& out, t_struct* tst for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { bool could_be_unset = (*f_iter)->get_req() == t_field::T_OPTIONAL; if (could_be_unset) { - indent(out) << "if (" << generate_isset_check(*f_iter) << ") {" << endl; + indent(out) << "if (" << generate_isset_check(*f_iter) << ") {" << '\n'; indent_up(); } t_field* field = (*f_iter); if (!first) { - indent(out) << "if (!first) sb.append(\", \");" << endl; + indent(out) << "if (!first) sb.append(\", \");" << '\n'; } - indent(out) << "sb.append(\"" << (*f_iter)->get_name() << ":\");" << endl; + indent(out) << "sb.append(\"" << (*f_iter)->get_name() << ":\");" << '\n'; bool can_be_null = type_can_be_null(field->get_type()); if (can_be_null) { - indent(out) << "if (this." << make_valid_java_identifier((*f_iter)->get_name()) << " == null) {" << endl; - indent(out) << " sb.append(\"null\");" << endl; - indent(out) << "} else {" << endl; + indent(out) << "if (this." << make_valid_java_identifier((*f_iter)->get_name()) << " == null) {" << '\n'; + indent(out) << " sb.append(\"null\");" << '\n'; + indent(out) << "} else {" << '\n'; indent_up(); } if (get_true_type(field->get_type())->is_binary()) { indent(out) << "org.apache.thrift.TBaseHelper.toString(this." << make_valid_java_identifier(field->get_name()) << ", sb);" - << endl; + << '\n'; } else if ((field->get_type()->is_set()) && (get_true_type(((t_set*)field->get_type())->get_elem_type())->is_binary())) { indent(out) << "org.apache.thrift.TBaseHelper.toString(this." << make_valid_java_identifier(field->get_name()) << ", sb);" - << endl; + << '\n'; } else if ((field->get_type()->is_list()) && (get_true_type(((t_list*)field->get_type())->get_elem_type())->is_binary())) { indent(out) << "org.apache.thrift.TBaseHelper.toString(this." << make_valid_java_identifier(field->get_name()) << ", sb);" - << endl; + << '\n'; } else { - indent(out) << "sb.append(this." << make_valid_java_identifier((*f_iter)->get_name()) << ");" << endl; + indent(out) << "sb.append(this." << make_valid_java_identifier((*f_iter)->get_name()) << ");" << '\n'; } if (can_be_null) { indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } - indent(out) << "first = false;" << endl; + indent(out) << "first = false;" << '\n'; if (could_be_unset) { indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } first = false; } - out << indent() << "sb.append(\")\");" << endl << indent() << "return sb.toString();" << endl; + out << indent() << "sb.append(\")\");" << '\n' << indent() << "return sb.toString();" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } /** @@ -2923,14 +2920,14 @@ void t_java_generator::generate_java_meta_data_map(ostream& out, t_struct* tstru // Static Map with fieldID -> org.apache.thrift.meta_data.FieldMetaData mappings indent(out) << "public static final java.util.Map<_Fields, " "org.apache.thrift.meta_data.FieldMetaData> metaDataMap;" - << endl; - indent(out) << "static {" << endl; + << '\n'; + indent(out) << "static {" << '\n'; indent_up(); indent(out) << "java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new " "java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);" - << endl; + << '\n'; // Populate map for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { @@ -2955,15 +2952,15 @@ void t_java_generator::generate_java_meta_data_map(ostream& out, t_struct* tstru if (annotations_as_metadata_) { generate_metadata_for_field_annotations(out, field); } - out << "));" << endl; + out << "));" << '\n'; } - indent(out) << "metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);" << endl; + indent(out) << "metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);" << '\n'; indent(out) << "org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(" - << type_name(tstruct) << ".class, metaDataMap);" << endl; + << type_name(tstruct) << ".class, metaDataMap);" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } /** @@ -3030,19 +3027,19 @@ void t_java_generator::generate_metadata_for_field_annotations(std::ostream& out if (field->annotations_.size() == 0) { return; } - out << ", " << endl; + out << ", " << '\n'; indent_up(); indent_up(); indent(out) << "java.util.stream.Stream.>builder()" - << endl; + << '\n'; indent_up(); indent_up(); for (auto& annotation : field->annotations_) { indent(out) << ".add(new java.util.AbstractMap.SimpleImmutableEntry<>(\"" + annotation.first + "\", \"" + annotation.second.back() + "\"))" - << endl; + << '\n'; } indent(out) << ".build().collect(java.util.stream.Collectors.toMap(java.util.Map.Entry::getKey, " "java.util.Map.Entry::getValue))"; @@ -3054,7 +3051,8 @@ void t_java_generator::generate_metadata_for_field_annotations(std::ostream& out } void t_java_generator::generate_field_value_meta_data(std::ostream& out, t_type* type) { - out << endl; + t_type* ttype = get_true_type(type); + out << '\n'; indent_up(); indent_up(); if (type->is_typedef()) { @@ -3123,7 +3121,7 @@ void t_java_generator::generate_service(t_service* tservice) { generate_javax_generated_annotation(f_service_); } f_service_ << java_suppressions(); - f_service_ << "public class " << make_valid_java_identifier(make_java_service_name_fix(service_name_)) << " {" << endl << endl; + f_service_ << "public class " << make_valid_java_identifier(service_name_) << " {" << '\n' << '\n'; indent_up(); // Generate the three main parts of the service @@ -3142,7 +3140,7 @@ void t_java_generator::generate_service(t_service* tservice) { generate_service_helpers(tservice); indent_down(); - f_service_ << "}" << endl; + f_service_ << "}" << '\n'; f_service_.close(); } @@ -3160,16 +3158,16 @@ void t_java_generator::generate_service_interface(t_service* tservice) { } generate_java_doc(f_service_, tservice); - f_service_ << indent() << "public interface Iface" << extends_iface << " {" << endl << endl; + f_service_ << indent() << "public interface Iface" << extends_iface << " {" << '\n' << '\n'; indent_up(); vector functions = tservice->get_functions(); vector::iterator f_iter; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { generate_java_doc(f_service_, *f_iter); - indent(f_service_) << "public " << function_signature(*f_iter) << ";" << endl << endl; + indent(f_service_) << "public " << function_signature(*f_iter) << ";" << '\n' << '\n'; } indent_down(); - f_service_ << indent() << "}" << endl << endl; + f_service_ << indent() << "}" << '\n' << '\n'; } void t_java_generator::generate_service_async_interface(t_service* tservice) { @@ -3180,17 +3178,17 @@ void t_java_generator::generate_service_async_interface(t_service* tservice) { extends_iface = " extends " + extends + ".AsyncIface"; } - f_service_ << indent() << "public interface AsyncIface" << extends_iface << " {" << endl << endl; + f_service_ << indent() << "public interface AsyncIface" << extends_iface << " {" << '\n' << '\n'; indent_up(); vector functions = tservice->get_functions(); vector::iterator f_iter; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { indent(f_service_) << "public " << function_signature_async(*f_iter, true) - << " throws org.apache.thrift.TException;" << endl - << endl; + << " throws org.apache.thrift.TException;" << '\n' + << '\n'; } indent_down(); - f_service_ << indent() << "}" << endl << endl; + f_service_ << indent() << "}" << '\n' << '\n'; } void t_java_generator::generate_service_future_interface(t_service* tservice) { @@ -3201,15 +3199,15 @@ void t_java_generator::generate_service_future_interface(t_service* tservice) { extends_iface = " extends " + extends + " .FutureIface"; } - f_service_ << indent() << "public interface FutureIface" << extends_iface << " {" << endl << endl; + f_service_ << indent() << "public interface FutureIface" << extends_iface << " {" << '\n' << '\n'; indent_up(); for (auto tfunc : tservice->get_functions()) { indent(f_service_) << "public " << function_signature_future(tfunc) - << " throws org.apache.thrift.TException;" << endl - << endl; + << " throws org.apache.thrift.TException;" << '\n' + << '\n'; } scope_down(f_service_); - f_service_ << endl << endl; + f_service_ << '\n' << '\n'; } /** @@ -3239,43 +3237,43 @@ void t_java_generator::generate_service_client(t_service* tservice) { } indent(f_service_) << "public static class Client extends " << extends_client - << " implements Iface {" << endl; + << " implements Iface {" << '\n'; indent_up(); indent(f_service_) << "public static class Factory implements org.apache.thrift.TServiceClientFactory {" - << endl; + << '\n'; indent_up(); - indent(f_service_) << "public Factory() {}" << endl; - indent(f_service_) << java_override_annotation() << endl; + indent(f_service_) << "public Factory() {}" << '\n'; + indent(f_service_) << java_override_annotation() << '\n'; indent(f_service_) << "public Client getClient(org.apache.thrift.protocol.TProtocol prot) {" - << endl; + << '\n'; indent_up(); - indent(f_service_) << "return new Client(prot);" << endl; + indent(f_service_) << "return new Client(prot);" << '\n'; indent_down(); - indent(f_service_) << "}" << endl; - indent(f_service_) << java_override_annotation() << endl; + indent(f_service_) << "}" << '\n'; + indent(f_service_) << java_override_annotation() << '\n'; indent(f_service_) << "public Client getClient(org.apache.thrift.protocol.TProtocol iprot, " "org.apache.thrift.protocol.TProtocol oprot) {" - << endl; + << '\n'; indent_up(); - indent(f_service_) << "return new Client(iprot, oprot);" << endl; + indent(f_service_) << "return new Client(iprot, oprot);" << '\n'; indent_down(); - indent(f_service_) << "}" << endl; + indent(f_service_) << "}" << '\n'; indent_down(); - indent(f_service_) << "}" << endl << endl; + indent(f_service_) << "}" << '\n' << '\n'; - indent(f_service_) << "public Client(org.apache.thrift.protocol.TProtocol prot)" << endl; + indent(f_service_) << "public Client(org.apache.thrift.protocol.TProtocol prot)" << '\n'; scope_up(f_service_); - indent(f_service_) << "super(prot, prot);" << endl; + indent(f_service_) << "super(prot, prot);" << '\n'; scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; indent(f_service_) << "public Client(org.apache.thrift.protocol.TProtocol iprot, " "org.apache.thrift.protocol.TProtocol oprot) {" - << endl; - indent(f_service_) << " super(iprot, oprot);" << endl; - indent(f_service_) << "}" << endl << endl; + << '\n'; + indent(f_service_) << " super(iprot, oprot);" << '\n'; + indent(f_service_) << "}" << '\n' << '\n'; // Generate client method implementations vector functions = tservice->get_functions(); @@ -3290,8 +3288,8 @@ void t_java_generator::generate_service_client(t_service* tservice) { } // Open function - indent(f_service_) << java_override_annotation() << endl; - indent(f_service_) << "public " << function_signature(*f_iter) << endl; + indent(f_service_) << java_override_annotation() << '\n'; + indent(f_service_) << "public " << function_signature(*f_iter) << '\n'; scope_up(f_service_); indent(f_service_) << "send" << sep << javaname << "("; @@ -3310,17 +3308,17 @@ void t_java_generator::generate_service_client(t_service* tservice) { } f_service_ << make_valid_java_identifier((*fld_iter)->get_name()); } - f_service_ << ");" << endl; + f_service_ << ");" << '\n'; if (!(*f_iter)->is_oneway()) { f_service_ << indent(); if (!(*f_iter)->get_returntype()->is_void()) { f_service_ << "return "; } - f_service_ << "recv" << sep << javaname << "();" << endl; + f_service_ << "recv" << sep << javaname << "();" << '\n'; } scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; t_function send_function(g_type_void, string("send") + sep + javaname, (*f_iter)->get_arglist()); @@ -3328,22 +3326,22 @@ void t_java_generator::generate_service_client(t_service* tservice) { string argsname = (*f_iter)->get_name() + "_args"; // Open function - indent(f_service_) << "public " << function_signature(&send_function) << endl; + indent(f_service_) << "public " << function_signature(&send_function) << '\n'; scope_up(f_service_); // Serialize the request - indent(f_service_) << argsname << " args = new " << argsname << "();" << endl; + indent(f_service_) << argsname << " args = new " << argsname << "();" << '\n'; for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) { indent(f_service_) << "args.set" << get_cap_name((*fld_iter)->get_name()) << "(" - << make_valid_java_identifier((*fld_iter)->get_name()) << ");" << endl; + << make_valid_java_identifier((*fld_iter)->get_name()) << ");" << '\n'; } const string sendBaseName = (*f_iter)->is_oneway() ? "sendBaseOneway" : "sendBase"; - indent(f_service_) << sendBaseName << "(\"" << funname << "\", args);" << endl; + indent(f_service_) << sendBaseName << "(\"" << funname << "\", args);" << '\n'; scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; if (!(*f_iter)->is_oneway()) { string resultname = (*f_iter)->get_name() + "_result"; @@ -3352,47 +3350,47 @@ void t_java_generator::generate_service_client(t_service* tservice) { t_function recv_function((*f_iter)->get_returntype(), string("recv") + sep + javaname, &noargs, (*f_iter)->get_xceptions()); // Open function - indent(f_service_) << "public " << function_signature(&recv_function) << endl; + indent(f_service_) << "public " << function_signature(&recv_function) << '\n'; scope_up(f_service_); - f_service_ << indent() << resultname << " result = new " << resultname << "();" << endl - << indent() << "receiveBase(result, \"" << funname << "\");" << endl; + f_service_ << indent() << resultname << " result = new " << resultname << "();" << '\n' + << indent() << "receiveBase(result, \"" << funname << "\");" << '\n'; // Careful, only return _result if not a void function if (!(*f_iter)->get_returntype()->is_void()) { - f_service_ << indent() << "if (result." << generate_isset_check("success") << ") {" << endl - << indent() << " return result.success;" << endl - << indent() << "}" << endl; + f_service_ << indent() << "if (result." << generate_isset_check("success") << ") {" << '\n' + << indent() << " return result.success;" << '\n' + << indent() << "}" << '\n'; } t_struct* xs = (*f_iter)->get_xceptions(); const std::vector& xceptions = xs->get_members(); vector::const_iterator x_iter; for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { - f_service_ << indent() << "if (result." << make_valid_java_identifier((*x_iter)->get_name()) << " != null) {" << endl - << indent() << " throw result." << make_valid_java_identifier((*x_iter)->get_name()) << ";" << endl - << indent() << "}" << endl; + f_service_ << indent() << "if (result." << make_valid_java_identifier((*x_iter)->get_name()) << " != null) {" << '\n' + << indent() << " throw result." << make_valid_java_identifier((*x_iter)->get_name()) << ";" << '\n' + << indent() << "}" << '\n'; } // If you get here it's an exception, unless a void function if ((*f_iter)->get_returntype()->is_void()) { - indent(f_service_) << "return;" << endl; + indent(f_service_) << "return;" << '\n'; } else { f_service_ << indent() << "throw new " "org.apache.thrift.TApplicationException(org.apache.thrift." "TApplicationException.MISSING_RESULT, \"" - << (*f_iter)->get_name() << " failed: unknown result\");" << endl; + << (*f_iter)->get_name() << " failed: unknown result\");" << '\n'; } // Close function scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; } } indent_down(); - indent(f_service_) << "}" << endl; + indent(f_service_) << "}" << '\n'; } void t_java_generator::generate_service_future_client(t_service* tservice) { @@ -3403,13 +3401,13 @@ void t_java_generator::generate_service_future_client(t_service* tservice) { static string adapter_class = "org.apache.thrift.async.AsyncMethodFutureAdapter"; indent(f_service_) << "public static class FutureClient " << extends_client - << "implements FutureIface {" << endl; + << "implements FutureIface {" << '\n'; indent_up(); - indent(f_service_) << "public FutureClient(AsyncIface delegate) {" << endl; + indent(f_service_) << "public FutureClient(AsyncIface delegate) {" << '\n'; indent_up(); - indent(f_service_) << "this.delegate = delegate;" << endl; + indent(f_service_) << "this.delegate = delegate;" << '\n'; scope_down(f_service_); - indent(f_service_) << "private final AsyncIface delegate;" << endl; + indent(f_service_) << "private final AsyncIface delegate;" << '\n'; for (auto tfunc : tservice->get_functions()) { string funname = tfunc->get_name(); string sep = "_"; @@ -3426,23 +3424,23 @@ void t_java_generator::generate_service_future_client(t_service* tservice) { string args_name = funname + "_args"; string result_name = funname + "_result"; - indent(f_service_) << "@Override" << endl; + indent(f_service_) << "@Override" << '\n'; indent(f_service_) << "public " << function_signature_future(tfunc) - << " throws org.apache.thrift.TException {" << endl; + << " throws org.apache.thrift.TException {" << '\n'; indent_up(); auto adapter = tmp("asyncMethodFutureAdapter"); indent(f_service_) << adapter_class << "<" << ret_type_name << "> " << adapter << " = " - << adapter_class << ".<" << ret_type_name << ">create();" << endl; + << adapter_class << ".<" << ret_type_name << ">create();" << '\n'; bool empty_args = tfunc->get_arglist()->get_members().empty(); indent(f_service_) << "delegate." << get_rpc_method_name(funname) << "(" << argument_list(tfunc->get_arglist(), false) << (empty_args ? "" : ", ") - << adapter << ");" << endl; - indent(f_service_) << "return " << adapter << ".getFuture();" << endl; + << adapter << ");" << '\n'; + indent(f_service_) << "return " << adapter << ".getFuture();" << '\n'; scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; } scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; } void t_java_generator::generate_service_async_client(t_service* tservice) { @@ -3452,41 +3450,41 @@ void t_java_generator::generate_service_async_client(t_service* tservice) { } indent(f_service_) << "public static class AsyncClient extends " << extends_client - << " implements AsyncIface {" << endl; + << " implements AsyncIface {" << '\n'; indent_up(); // Factory method indent(f_service_) << "public static class Factory implements " "org.apache.thrift.async.TAsyncClientFactory {" - << endl; + << '\n'; indent(f_service_) << " private org.apache.thrift.async.TAsyncClientManager clientManager;" - << endl; + << '\n'; indent(f_service_) << " private org.apache.thrift.protocol.TProtocolFactory protocolFactory;" - << endl; + << '\n'; indent(f_service_) << " public Factory(org.apache.thrift.async.TAsyncClientManager " "clientManager, org.apache.thrift.protocol.TProtocolFactory " "protocolFactory) {" - << endl; - indent(f_service_) << " this.clientManager = clientManager;" << endl; - indent(f_service_) << " this.protocolFactory = protocolFactory;" << endl; - indent(f_service_) << " }" << endl; - indent(f_service_) << java_override_annotation() << endl; + << '\n'; + indent(f_service_) << " this.clientManager = clientManager;" << '\n'; + indent(f_service_) << " this.protocolFactory = protocolFactory;" << '\n'; + indent(f_service_) << " }" << '\n'; + indent(f_service_) << java_override_annotation() << '\n'; indent(f_service_) << " public AsyncClient " "getAsyncClient(org.apache.thrift.transport.TNonblockingTransport " "transport) {" - << endl; + << '\n'; indent(f_service_) << " return new AsyncClient(protocolFactory, clientManager, transport);" - << endl; - indent(f_service_) << " }" << endl; - indent(f_service_) << "}" << endl << endl; + << '\n'; + indent(f_service_) << " }" << '\n'; + indent(f_service_) << "}" << '\n' << '\n'; indent(f_service_) << "public AsyncClient(org.apache.thrift.protocol.TProtocolFactory " "protocolFactory, org.apache.thrift.async.TAsyncClientManager " "clientManager, org.apache.thrift.transport.TNonblockingTransport " "transport) {" - << endl; - indent(f_service_) << " super(protocolFactory, clientManager, transport);" << endl; - indent(f_service_) << "}" << endl << endl; + << '\n'; + indent(f_service_) << " super(protocolFactory, clientManager, transport);" << '\n'; + indent(f_service_) << "}" << '\n' << '\n'; // Generate client method implementations vector functions = tservice->get_functions(); @@ -3509,35 +3507,35 @@ void t_java_generator::generate_service_async_client(t_service* tservice) { string result_name = (*f_iter)->get_name() + "_result"; // Main method body - indent(f_service_) << java_override_annotation() << endl; + indent(f_service_) << java_override_annotation() << '\n'; indent(f_service_) << "public " << function_signature_async(*f_iter, false) - << " throws org.apache.thrift.TException {" << endl; - indent(f_service_) << " checkReady();" << endl; + << " throws org.apache.thrift.TException {" << '\n'; + indent(f_service_) << " checkReady();" << '\n'; indent(f_service_) << " " << funclassname << " method_call = new " + funclassname + "(" << async_argument_list(*f_iter, arg_struct, ret_type) - << ", this, ___protocolFactory, ___transport);" << endl; - indent(f_service_) << " this.___currentMethod = method_call;" << endl; - indent(f_service_) << " ___manager.call(method_call);" << endl; - indent(f_service_) << "}" << endl; + << ", this, ___protocolFactory, ___transport);" << '\n'; + indent(f_service_) << " this.___currentMethod = method_call;" << '\n'; + indent(f_service_) << " ___manager.call(method_call);" << '\n'; + indent(f_service_) << "}" << '\n'; - f_service_ << endl; + f_service_ << '\n'; // TAsyncMethod object for this function call indent(f_service_) << "public static class " + funclassname + " extends org.apache.thrift.async.TAsyncMethodCall<" + type_name((*f_iter)->get_returntype(), true) + "> {" - << endl; + << '\n'; indent_up(); // Member variables for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) { indent(f_service_) << "private " + type_name((*fld_iter)->get_type()) + " " + make_valid_java_identifier((*fld_iter)->get_name()) + ";" - << endl; + << '\n'; } // NOTE since we use a new Client instance to deserialize, let's keep seqid to 0 for now - // indent(f_service_) << "private int seqid;" << endl << endl; + // indent(f_service_) << "private int seqid;" << '\n' << '\n'; // Constructor indent(f_service_) << "public " + funclassname + "(" @@ -3546,22 +3544,22 @@ void t_java_generator::generate_service_async_client(t_service* tservice) { "org.apache.thrift.protocol.TProtocolFactory protocolFactory, " "org.apache.thrift.transport.TNonblockingTransport transport) throws " "org.apache.thrift.TException {" - << endl; + << '\n'; indent(f_service_) << " super(client, protocolFactory, transport, resultHandler, " - << ((*f_iter)->is_oneway() ? "true" : "false") << ");" << endl; + << ((*f_iter)->is_oneway() ? "true" : "false") << ");" << '\n'; // Assign member variables for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) { indent(f_service_) << " this." + make_valid_java_identifier((*fld_iter)->get_name()) + " = " + make_valid_java_identifier((*fld_iter)->get_name()) + ";" - << endl; + << '\n'; } - indent(f_service_) << "}" << endl << endl; - indent(f_service_) << java_override_annotation() << endl; + indent(f_service_) << "}" << '\n' << '\n'; + indent(f_service_) << java_override_annotation() << '\n'; indent(f_service_) << "public void write_args(org.apache.thrift.protocol.TProtocol prot) " "throws org.apache.thrift.TException {" - << endl; + << '\n'; indent_up(); // Serialize request @@ -3569,68 +3567,68 @@ void t_java_generator::generate_service_async_client(t_service* tservice) { f_service_ << indent() << "prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage(\"" << funname << "\", org.apache.thrift.protocol." << ((*f_iter)->is_oneway() ? "TMessageType.ONEWAY" : "TMessageType.CALL") << ", 0));" - << endl - << indent() << args_name << " args = new " << args_name << "();" << endl; + << '\n' + << indent() << args_name << " args = new " << args_name << "();" << '\n'; for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) { f_service_ << indent() << "args.set" << get_cap_name((*fld_iter)->get_name()) << "(" - << make_valid_java_identifier((*fld_iter)->get_name()) << ");" << endl; + << make_valid_java_identifier((*fld_iter)->get_name()) << ");" << '\n'; } - f_service_ << indent() << "args.write(prot);" << endl - << indent() << "prot.writeMessageEnd();" << endl; + f_service_ << indent() << "args.write(prot);" << '\n' + << indent() << "prot.writeMessageEnd();" << '\n'; indent_down(); - indent(f_service_) << "}" << endl << endl; + indent(f_service_) << "}" << '\n' << '\n'; // Return method - indent(f_service_) << java_override_annotation() << endl; + indent(f_service_) << java_override_annotation() << '\n'; indent(f_service_) << "public " + type_name(ret_type, true) + " getResult() throws "; vector::const_iterator x_iter; for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { f_service_ << type_name((*x_iter)->get_type(), false, false) + ", "; } - f_service_ << "org.apache.thrift.TException {" << endl; + f_service_ << "org.apache.thrift.TException {" << '\n'; indent_up(); f_service_ << indent() << "if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {" - << endl + << '\n' << indent() << " throw new java.lang.IllegalStateException(\"Method call not finished!\");" - << endl - << indent() << "}" << endl + << '\n' + << indent() << "}" << '\n' << indent() << "org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new " "org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());" - << endl + << '\n' << indent() << "org.apache.thrift.protocol.TProtocol prot = " "client.getProtocolFactory().getProtocol(memoryTransport);" - << endl; + << '\n'; indent(f_service_); if (ret_type->is_void()) { // NB: Includes oneways which always return void. if (!(*f_iter)->is_oneway()) { - f_service_ << "(new Client(prot)).recv" + sep + javaname + "();" << endl; + f_service_ << "(new Client(prot)).recv" + sep + javaname + "();" << '\n'; indent(f_service_); } - f_service_ << "return null;" << endl; + f_service_ << "return null;" << '\n'; } else { - f_service_ << "return (new Client(prot)).recv" + sep + javaname + "();" << endl; + f_service_ << "return (new Client(prot)).recv" + sep + javaname + "();" << '\n'; } // Close function indent_down(); - indent(f_service_) << "}" << endl; + indent(f_service_) << "}" << '\n'; // Close class indent_down(); - indent(f_service_) << "}" << endl << endl; + indent(f_service_) << "}" << '\n' << '\n'; } // Close AsyncClient scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; } /** @@ -3655,41 +3653,42 @@ void t_java_generator::generate_service_server(t_service* tservice) { // Generate the header portion indent(f_service_) << "public static class Processor extends " - << extends_processor << " implements org.apache.thrift.TProcessor {" << endl; + << extends_processor << " implements org.apache.thrift.TProcessor {" << '\n'; indent_up(); indent(f_service_) << "private static final org.slf4j.Logger _LOGGER = " "org.slf4j.LoggerFactory.getLogger(Processor.class.getName());" - << endl; + << '\n'; - indent(f_service_) << "public Processor(I iface) {" << endl; + indent(f_service_) << "public Processor(I iface) {" << '\n'; indent(f_service_) << " super(iface, getProcessMap(new java.util.HashMap>()));" - << endl; - indent(f_service_) << "}" << endl << endl; + "org.apache.thrift.TBase, ? extends org.apache.thrift.TBase>>()));" + << '\n'; + indent(f_service_) << "}" << '\n' << '\n'; indent(f_service_) << "protected Processor(I iface, java.util.Map> " - "processMap) {" - << endl; - indent(f_service_) << " super(iface, getProcessMap(processMap));" << endl; - indent(f_service_) << "}" << endl << endl; - - indent(f_service_) << "private static java.util.Map> " + "org.apache.thrift.ProcessFunction> processMap) {" + << '\n'; + indent(f_service_) << " super(iface, getProcessMap(processMap));" << '\n'; + indent(f_service_) << "}" << '\n' << '\n'; + + indent(f_service_) << "private static java.util.Map> " "getProcessMap(java.util.Map> processMap) {" - << endl; + " org.apache.thrift.TBase, ? extends org.apache.thrift.TBase>> processMap) {" + << '\n'; indent_up(); for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { indent(f_service_) << "processMap.put(\"" << (*f_iter)->get_name() << "\", new " - << make_valid_java_identifier((*f_iter)->get_name()) << "());" << endl; + << make_valid_java_identifier((*f_iter)->get_name()) << "());" << '\n'; } - indent(f_service_) << "return processMap;" << endl; + indent(f_service_) << "return processMap;" << '\n'; indent_down(); - indent(f_service_) << "}" << endl << endl; + indent(f_service_) << "}" << '\n' << '\n'; // Generate the process subfunctions for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { @@ -3697,7 +3696,7 @@ void t_java_generator::generate_service_server(t_service* tservice) { } indent_down(); - indent(f_service_) << "}" << endl << endl; + indent(f_service_) << "}" << '\n' << '\n'; } /** @@ -3722,42 +3721,42 @@ void t_java_generator::generate_service_async_server(t_service* tservice) { // Generate the header portion indent(f_service_) << "public static class AsyncProcessor extends " - << extends_processor << " {" << endl; + << extends_processor << " {" << '\n'; indent_up(); indent(f_service_) << "private static final org.slf4j.Logger _LOGGER = " "org.slf4j.LoggerFactory.getLogger(AsyncProcessor.class.getName());" - << endl; + << '\n'; - indent(f_service_) << "public AsyncProcessor(I iface) {" << endl; + indent(f_service_) << "public AsyncProcessor(I iface) {" << '\n'; indent(f_service_) << " super(iface, getProcessMap(new java.util.HashMap>()));" - << endl; - indent(f_service_) << "}" << endl << endl; + "org.apache.thrift.TBase, ?, ? extends org.apache.thrift.TBase>>()));" + << '\n'; + indent(f_service_) << "}" << '\n' << '\n'; indent(f_service_) << "protected AsyncProcessor(I iface, java.util.Map> processMap) {" - << endl; - indent(f_service_) << " super(iface, getProcessMap(processMap));" << endl; - indent(f_service_) << "}" << endl << endl; + "org.apache.thrift.TBase, ?, ? extends org.apache.thrift.TBase>> processMap) {" + << '\n'; + indent(f_service_) << " super(iface, getProcessMap(processMap));" << '\n'; + indent(f_service_) << "}" << '\n' << '\n'; indent(f_service_) << "private static java.util.Map> getProcessMap(java.util.Map> getProcessMap(java.util.Map> processMap) {" - << endl; + "org.apache.thrift.TBase, ?, ? extends org.apache.thrift.TBase>> processMap) {" + << '\n'; indent_up(); for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { indent(f_service_) << "processMap.put(\"" << (*f_iter)->get_name() << "\", new " - << make_valid_java_identifier((*f_iter)->get_name()) << "());" << endl; + << make_valid_java_identifier((*f_iter)->get_name()) << "());" << '\n'; } - indent(f_service_) << "return processMap;" << endl; + indent(f_service_) << "return processMap;" << '\n'; indent_down(); - indent(f_service_) << "}" << endl << endl; + indent(f_service_) << "}" << '\n' << '\n'; // Generate the process subfunctions for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { @@ -3765,7 +3764,7 @@ void t_java_generator::generate_service_async_server(t_service* tservice) { } indent_down(); - indent(f_service_) << "}" << endl << endl; + indent(f_service_) << "}" << '\n' << '\n'; } /** @@ -3813,91 +3812,101 @@ void t_java_generator::generate_process_async_function(t_service* tservice, t_fu // Open class indent(f_service_) << "public static class " << make_valid_java_identifier(tfunction->get_name()) << " extends org.apache.thrift.AsyncProcessFunction {" << endl; + << argsname << ", " << resulttype << ", " << resultname << "> {" << '\n'; indent_up(); - indent(f_service_) << "public " << make_valid_java_identifier(tfunction->get_name()) << "() {" << endl; - indent(f_service_) << " super(\"" << tfunction->get_name() << "\");" << endl; - indent(f_service_) << "}" << endl << endl; + indent(f_service_) << "public " << make_valid_java_identifier(tfunction->get_name()) << "() {" << '\n'; + indent(f_service_) << " super(\"" << tfunction->get_name() << "\");" << '\n'; + indent(f_service_) << "}" << '\n' << '\n'; + + indent(f_service_) << java_override_annotation() << '\n'; + indent(f_service_) << "public " << resultname << " getEmptyResultInstance() {" << '\n'; + if (tfunction->is_oneway()) { + indent(f_service_) << " return null;" << '\n'; + } + else { + indent(f_service_) << " return new " << resultname << "();" << '\n'; + } + indent(f_service_) << "}" << '\n' << '\n'; - indent(f_service_) << java_override_annotation() << endl; - indent(f_service_) << "public " << argsname << " getEmptyArgsInstance() {" << endl; - indent(f_service_) << " return new " << argsname << "();" << endl; - indent(f_service_) << "}" << endl << endl; + indent(f_service_) << java_override_annotation() << '\n'; + indent(f_service_) << "public " << argsname << " getEmptyArgsInstance() {" << '\n'; + indent(f_service_) << " return new " << argsname << "();" << '\n'; + indent(f_service_) << "}" << '\n' << '\n'; - indent(f_service_) << java_override_annotation() << endl; + indent(f_service_) << java_override_annotation() << '\n'; indent(f_service_) << "public org.apache.thrift.async.AsyncMethodCallback<" << resulttype << "> getResultHandler(final " "org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, " "final int seqid) {" - << endl; + << '\n'; indent_up(); - indent(f_service_) << "final org.apache.thrift.AsyncProcessFunction fcall = this;" << endl; + indent(f_service_) << "final org.apache.thrift.AsyncProcessFunction fcall = this;" << '\n'; indent(f_service_) << "return new org.apache.thrift.async.AsyncMethodCallback<" << resulttype - << ">() { " << endl; + << ">() { " << '\n'; indent_up(); - indent(f_service_) << java_override_annotation() << endl; - indent(f_service_) << "public void onComplete(" << resulttype << " o) {" << endl; + indent(f_service_) << java_override_annotation() << '\n'; + indent(f_service_) << "public void onComplete(" << resulttype << " o) {" << '\n'; indent_up(); if (!tfunction->is_oneway()) { - indent(f_service_) << resultname << " result = new " << resultname << "();" << endl; + indent(f_service_) << resultname << " result = new " << resultname << "();" << '\n'; if (!tfunction->get_returntype()->is_void()) { - indent(f_service_) << "result.success = o;" << endl; + indent(f_service_) << "result.success = o;" << '\n'; // Set isset on success field if (!type_can_be_null(tfunction->get_returntype())) { indent(f_service_) << "result.set" << get_cap_name("success") << get_cap_name("isSet") - << "(true);" << endl; + << "(true);" << '\n'; } } - indent(f_service_) << "try {" << endl; + indent(f_service_) << "try {" << '\n'; indent(f_service_) << " fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);" - << endl; - indent(f_service_) << "} catch (org.apache.thrift.transport.TTransportException e) {" << endl; + << '\n'; + indent(f_service_) << "} catch (org.apache.thrift.transport.TTransportException e) {" << '\n'; indent_up(); f_service_ << indent() << "_LOGGER.error(\"TTransportException writing to internal frame buffer\", e);" - << endl - << indent() << "fb.close();" << endl; + << '\n' + << indent() << "fb.close();" << '\n'; indent_down(); - indent(f_service_) << "} catch (java.lang.Exception e) {" << endl; + indent(f_service_) << "} catch (java.lang.Exception e) {" << '\n'; indent_up(); f_service_ << indent() << "_LOGGER.error(\"Exception writing to internal frame buffer\", e);" - << endl - << indent() << "onError(e);" << endl; + << '\n' + << indent() << "onError(e);" << '\n'; indent_down(); - indent(f_service_) << "}" << endl; + indent(f_service_) << "}" << '\n'; } indent_down(); - indent(f_service_) << "}" << endl; + indent(f_service_) << "}" << '\n'; - indent(f_service_) << java_override_annotation() << endl; - indent(f_service_) << "public void onError(java.lang.Exception e) {" << endl; + indent(f_service_) << java_override_annotation() << '\n'; + indent(f_service_) << "public void onError(java.lang.Exception e) {" << '\n'; indent_up(); if (tfunction->is_oneway()) { indent(f_service_) << "if (e instanceof org.apache.thrift.transport.TTransportException) {" - << endl; + << '\n'; indent_up(); - f_service_ << indent() << "_LOGGER.error(\"TTransportException inside handler\", e);" << endl - << indent() << "fb.close();" << endl; + f_service_ << indent() << "_LOGGER.error(\"TTransportException inside handler\", e);" << '\n' + << indent() << "fb.close();" << '\n'; indent_down(); - indent(f_service_) << "} else {" << endl; + indent(f_service_) << "} else {" << '\n'; indent_up(); - f_service_ << indent() << "_LOGGER.error(\"Exception inside oneway handler\", e);" << endl; + f_service_ << indent() << "_LOGGER.error(\"Exception inside oneway handler\", e);" << '\n'; indent_down(); - indent(f_service_) << "}" << endl; + indent(f_service_) << "}" << '\n'; } else { - indent(f_service_) << "byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;" << endl; - indent(f_service_) << "org.apache.thrift.TSerializable msg;" << endl; - indent(f_service_) << resultname << " result = new " << resultname << "();" << endl; + indent(f_service_) << "byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;" << '\n'; + indent(f_service_) << "org.apache.thrift.TSerializable msg;" << '\n'; + indent(f_service_) << resultname << " result = new " << resultname << "();" << '\n'; t_struct* xs = tfunction->get_xceptions(); const std::vector& xceptions = xs->get_members(); @@ -3909,66 +3918,66 @@ void t_java_generator::generate_process_async_function(t_service* tservice, t_fu f_service_ << indent(); string type = type_name((*x_iter)->get_type(), false, false); string name = (*x_iter)->get_name(); - f_service_ << "if (e instanceof " << type << ") {" << endl; + f_service_ << "if (e instanceof " << type << ") {" << '\n'; indent_up(); - f_service_ << indent() << "result." << make_valid_java_identifier(name) << " = (" << type << ") e;" << endl + f_service_ << indent() << "result." << make_valid_java_identifier(name) << " = (" << type << ") e;" << '\n' << indent() << "result.set" << get_cap_name(name) << get_cap_name("isSet") - << "(true);" << endl - << indent() << "msg = result;" << endl; + << "(true);" << '\n' + << indent() << "msg = result;" << '\n'; indent_down(); indent(f_service_) << "} else "; } } else { indent(f_service_); } - f_service_ << "if (e instanceof org.apache.thrift.transport.TTransportException) {" << endl; + f_service_ << "if (e instanceof org.apache.thrift.transport.TTransportException) {" << '\n'; indent_up(); - f_service_ << indent() << "_LOGGER.error(\"TTransportException inside handler\", e);" << endl - << indent() << "fb.close();" << endl - << indent() << "return;" << endl; + f_service_ << indent() << "_LOGGER.error(\"TTransportException inside handler\", e);" << '\n' + << indent() << "fb.close();" << '\n' + << indent() << "return;" << '\n'; indent_down(); indent(f_service_) << "} else if (e instanceof org.apache.thrift.TApplicationException) {" - << endl; + << '\n'; indent_up(); - f_service_ << indent() << "_LOGGER.error(\"TApplicationException inside handler\", e);" << endl - << indent() << "msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;" << endl - << indent() << "msg = (org.apache.thrift.TApplicationException)e;" << endl; + f_service_ << indent() << "_LOGGER.error(\"TApplicationException inside handler\", e);" << '\n' + << indent() << "msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;" << '\n' + << indent() << "msg = (org.apache.thrift.TApplicationException)e;" << '\n'; indent_down(); - indent(f_service_) << "} else {" << endl; + indent(f_service_) << "} else {" << '\n'; indent_up(); - f_service_ << indent() << "_LOGGER.error(\"Exception inside handler\", e);" << endl - << indent() << "msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;" << endl + f_service_ << indent() << "_LOGGER.error(\"Exception inside handler\", e);" << '\n' + << indent() << "msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;" << '\n' << indent() << "msg = new " "org.apache.thrift.TApplicationException(org.apache.thrift." "TApplicationException.INTERNAL_ERROR, e.getMessage());" - << endl; + << '\n'; indent_down(); - f_service_ << indent() << "}" << endl - << indent() << "try {" << endl - << indent() << " fcall.sendResponse(fb,msg,msgType,seqid);" << endl - << indent() << "} catch (java.lang.Exception ex) {" << endl + f_service_ << indent() << "}" << '\n' + << indent() << "try {" << '\n' + << indent() << " fcall.sendResponse(fb,msg,msgType,seqid);" << '\n' + << indent() << "} catch (java.lang.Exception ex) {" << '\n' << indent() << " _LOGGER.error(\"Exception writing to internal frame buffer\", ex);" - << endl - << indent() << " fb.close();" << endl - << indent() << "}" << endl; + << '\n' + << indent() << " fb.close();" << '\n' + << indent() << "}" << '\n'; } indent_down(); - indent(f_service_) << "}" << endl; + indent(f_service_) << "}" << '\n'; indent_down(); - indent(f_service_) << "};" << endl; + indent(f_service_) << "};" << '\n'; indent_down(); - indent(f_service_) << "}" << endl << endl; + indent(f_service_) << "}" << '\n' << '\n'; - indent(f_service_) << java_override_annotation() << endl; - indent(f_service_) << "protected boolean isOneway() {" << endl; - indent(f_service_) << " return " << ((tfunction->is_oneway()) ? "true" : "false") << ";" << endl; - indent(f_service_) << "}" << endl << endl; + indent(f_service_) << java_override_annotation() << '\n'; + indent(f_service_) << "public boolean isOneway() {" << '\n'; + indent(f_service_) << " return " << ((tfunction->is_oneway()) ? "true" : "false") << ";" << '\n'; + indent(f_service_) << "}" << '\n' << '\n'; - indent(f_service_) << java_override_annotation() << endl; + indent(f_service_) << java_override_annotation() << '\n'; indent(f_service_) << "public void start(I iface, " << argsname << " args, org.apache.thrift.async.AsyncMethodCallback<" << resulttype - << "> resultHandler) throws org.apache.thrift.TException {" << endl; + << "> resultHandler) throws org.apache.thrift.TException {" << '\n'; indent_up(); // Generate the function call @@ -3990,17 +3999,17 @@ void t_java_generator::generate_process_async_function(t_service* tservice, t_fu if (!first) f_service_ << ","; f_service_ << "resultHandler"; - f_service_ << ");" << endl; + f_service_ << ");" << '\n'; indent_down(); indent(f_service_) << "}"; // Close function - f_service_ << endl; + f_service_ << '\n'; // Close class indent_down(); - f_service_ << indent() << "}" << endl << endl; + f_service_ << indent() << "}" << '\n' << '\n'; } /** @@ -4019,35 +4028,45 @@ void t_java_generator::generate_process_function(t_service* tservice, t_function // Open class indent(f_service_) << "public static class " << make_valid_java_identifier(tfunction->get_name()) << " extends org.apache.thrift.ProcessFunction {" << endl; + << argsname << ", " << resultname << "> {" << '\n'; indent_up(); - indent(f_service_) << "public " << make_valid_java_identifier(tfunction->get_name()) << "() {" << endl; - indent(f_service_) << " super(\"" << tfunction->get_name() << "\");" << endl; - indent(f_service_) << "}" << endl << endl; + indent(f_service_) << "public " << make_valid_java_identifier(tfunction->get_name()) << "() {" << '\n'; + indent(f_service_) << " super(\"" << tfunction->get_name() << "\");" << '\n'; + indent(f_service_) << "}" << '\n' << '\n'; - indent(f_service_) << java_override_annotation() << endl; - indent(f_service_) << "public " << argsname << " getEmptyArgsInstance() {" << endl; - indent(f_service_) << " return new " << argsname << "();" << endl; - indent(f_service_) << "}" << endl << endl; + indent(f_service_) << java_override_annotation() << '\n'; + indent(f_service_) << "public " << argsname << " getEmptyArgsInstance() {" << '\n'; + indent(f_service_) << " return new " << argsname << "();" << '\n'; + indent(f_service_) << "}" << '\n' << '\n'; - indent(f_service_) << java_override_annotation() << endl; - indent(f_service_) << "protected boolean isOneway() {" << endl; - indent(f_service_) << " return " << ((tfunction->is_oneway()) ? "true" : "false") << ";" << endl; - indent(f_service_) << "}" << endl << endl; + indent(f_service_) << java_override_annotation() << '\n'; + indent(f_service_) << "public boolean isOneway() {" << '\n'; + indent(f_service_) << " return " << ((tfunction->is_oneway()) ? "true" : "false") << ";" << '\n'; + indent(f_service_) << "}" << '\n' << '\n'; - indent(f_service_) << java_override_annotation() << endl; - indent(f_service_) << "protected boolean rethrowUnhandledExceptions() {" << endl; + indent(f_service_) << java_override_annotation() << '\n'; + indent(f_service_) << "protected boolean rethrowUnhandledExceptions() {" << '\n'; indent(f_service_) << " return " << ((rethrow_unhandled_exceptions_) ? "true" : "false") << ";" - << endl; - indent(f_service_) << "}" << endl << endl; + << '\n'; + indent(f_service_) << "}" << '\n' << '\n'; + + indent(f_service_) << java_override_annotation() << '\n'; + indent(f_service_) << "public " << resultname << " getEmptyResultInstance() {" << '\n'; + if (tfunction->is_oneway()) { + indent(f_service_) << " return null;" << '\n'; + } + else { + indent(f_service_) << " return new " << resultname << "();" << '\n'; + } + indent(f_service_) << "}" << '\n' << '\n'; - indent(f_service_) << java_override_annotation() << endl; + indent(f_service_) << java_override_annotation() << '\n'; indent(f_service_) << "public " << resultname << " getResult(I iface, " << argsname - << " args) throws org.apache.thrift.TException {" << endl; + << " args) throws org.apache.thrift.TException {" << '\n'; indent_up(); if (!tfunction->is_oneway()) { - indent(f_service_) << resultname << " result = new " << resultname << "();" << endl; + indent(f_service_) << resultname << " result = getEmptyResultInstance();" << '\n'; } t_struct* xs = tfunction->get_xceptions(); @@ -4056,7 +4075,7 @@ void t_java_generator::generate_process_function(t_service* tservice, t_function // Try block for a function with exceptions if (xceptions.size() > 0) { - f_service_ << indent() << "try {" << endl; + f_service_ << indent() << "try {" << '\n'; indent_up(); } @@ -4079,13 +4098,13 @@ void t_java_generator::generate_process_function(t_service* tservice, t_function } f_service_ << "args." << make_valid_java_identifier((*f_iter)->get_name()); } - f_service_ << ");" << endl; + f_service_ << ");" << '\n'; // Set isset on success field if (!tfunction->is_oneway() && !tfunction->get_returntype()->is_void() && !type_can_be_null(tfunction->get_returntype())) { indent(f_service_) << "result.set" << get_cap_name("success") << get_cap_name("isSet") - << "(true);" << endl; + << "(true);" << '\n'; } if (!tfunction->is_oneway() && xceptions.size() > 0) { @@ -4093,34 +4112,34 @@ void t_java_generator::generate_process_function(t_service* tservice, t_function f_service_ << indent() << "}"; for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { f_service_ << " catch (" << type_name((*x_iter)->get_type(), false, false) << " " - << make_valid_java_identifier((*x_iter)->get_name()) << ") {" << endl; + << make_valid_java_identifier((*x_iter)->get_name()) << ") {" << '\n'; if (!tfunction->is_oneway()) { indent_up(); f_service_ << indent() << "result." << make_valid_java_identifier((*x_iter)->get_name()) << " = " - << make_valid_java_identifier((*x_iter)->get_name()) << ";" << endl; + << make_valid_java_identifier((*x_iter)->get_name()) << ";" << '\n'; indent_down(); f_service_ << indent() << "}"; } else { f_service_ << "}"; } } - f_service_ << endl; + f_service_ << '\n'; } if (tfunction->is_oneway()) { - indent(f_service_) << "return null;" << endl; + indent(f_service_) << "return null;" << '\n'; } else { - indent(f_service_) << "return result;" << endl; + indent(f_service_) << "return result;" << '\n'; } indent_down(); indent(f_service_) << "}"; // Close function - f_service_ << endl; + f_service_ << '\n'; // Close class indent_down(); - f_service_ << indent() << "}" << endl << endl; + f_service_ << indent() << "}" << '\n' << '\n'; } /** @@ -4184,12 +4203,12 @@ void t_java_generator::generate_deserialize_field(ostream& out, default: throw "compiler error: no Java name for base type " + t_base_type::t_base_name(tbase); } - out << endl; + out << '\n'; } else if (type->is_enum()) { indent(out) << name << " = " << type_name(tfield->get_type(), true, false, false, true) + ".findByValue(iprot.readI32());" - << endl; + << '\n'; } else { printf("DO NOT KNOW HOW TO DESERIALIZE FIELD '%s' TYPE '%s'\n", tfield->get_name().c_str(), type_name(type).c_str()); @@ -4202,15 +4221,15 @@ void t_java_generator::generate_deserialize_field(ostream& out, void t_java_generator::generate_deserialize_struct(ostream& out, t_struct* tstruct, string prefix) { if (reuse_objects_) { - indent(out) << "if (" << prefix << " == null) {" << endl; + indent(out) << "if (" << prefix << " == null) {" << '\n'; indent_up(); } - indent(out) << prefix << " = new " << type_name(tstruct) << "();" << endl; + indent(out) << prefix << " = new " << type_name(tstruct) << "();" << '\n'; if (reuse_objects_) { indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } - indent(out) << prefix << ".read(iprot);" << endl; + indent(out) << prefix << ".read(iprot);" << '\n'; } /** @@ -4237,31 +4256,31 @@ void t_java_generator::generate_deserialize_container(ostream& out, // Declare variables, read header if (ttype->is_map()) { indent(out) << "org.apache.thrift.protocol.TMap " << obj << " = iprot.readMapBegin();" - << endl; + << '\n'; } else if (ttype->is_set()) { indent(out) << "org.apache.thrift.protocol.TSet " << obj << " = iprot.readSetBegin();" - << endl; + << '\n'; } else if (ttype->is_list()) { indent(out) << "org.apache.thrift.protocol.TList " << obj << " = iprot.readListBegin();" - << endl; + << '\n'; } } else { // Declare variables, read header if (ttype->is_map()) { indent(out) << "org.apache.thrift.protocol.TMap " << obj << " = iprot.readMapBegin(" << type_to_enum(((t_map*)ttype)->get_key_type()) << ", " - << type_to_enum(((t_map*)ttype)->get_val_type()) << "); " << endl; + << type_to_enum(((t_map*)ttype)->get_val_type()) << "); " << '\n'; } else if (ttype->is_set()) { indent(out) << "org.apache.thrift.protocol.TSet " << obj << " = iprot.readSetBegin(" - << type_to_enum(((t_set*)ttype)->get_elem_type()) << ");" << endl; + << type_to_enum(((t_set*)ttype)->get_elem_type()) << ");" << '\n'; } else if (ttype->is_list()) { indent(out) << "org.apache.thrift.protocol.TList " << obj << " = iprot.readListBegin(" - << type_to_enum(((t_list*)ttype)->get_elem_type()) << ");" << endl; + << type_to_enum(((t_list*)ttype)->get_elem_type()) << ");" << '\n'; } } if (reuse_objects_) { - indent(out) << "if (" << prefix << " == null) {" << endl; + indent(out) << "if (" << prefix << " == null) {" << '\n'; indent_up(); } @@ -4273,18 +4292,18 @@ void t_java_generator::generate_deserialize_container(ostream& out, // construct the collection correctly i.e. with appropriate size/type if (is_enum_set(ttype) || is_enum_map(ttype)) { - out << "(" << inner_enum_type_name(ttype) << ");" << endl; + out << "(" << inner_enum_type_name(ttype) << ");" << '\n'; } else if (sorted_containers_ && (ttype->is_map() || ttype->is_set())) { // TreeSet and TreeMap don't have any constructor which takes a capacity as an argument - out << "();" << endl; + out << "();" << '\n'; } else { out << "(" << (ttype->is_list() ? "" : "2*") << obj << ".size" - << ");" << endl; + << ");" << '\n'; } if (reuse_objects_) { indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } if (ttype->is_map()) { @@ -4300,11 +4319,11 @@ void t_java_generator::generate_deserialize_container(ostream& out, if (has_metadata) { // Read container end if (ttype->is_map()) { - indent(out) << "iprot.readMapEnd();" << endl; + indent(out) << "iprot.readMapEnd();" << '\n'; } else if (ttype->is_set()) { - indent(out) << "iprot.readSetEnd();" << endl; + indent(out) << "iprot.readSetEnd();" << '\n'; } else if (ttype->is_list()) { - indent(out) << "iprot.readListEnd();" << endl; + indent(out) << "iprot.readListEnd();" << '\n'; } } scope_down(out); @@ -4323,14 +4342,14 @@ void t_java_generator::generate_deserialize_map_element(ostream& out, t_field fkey(tmap->get_key_type(), key); t_field fval(tmap->get_val_type(), val); - indent(out) << declare_field(&fkey, reuse_objects_, false) << endl; - indent(out) << declare_field(&fval, reuse_objects_, false) << endl; + indent(out) << declare_field(&fkey, reuse_objects_, false) << '\n'; + indent(out) << declare_field(&fval, reuse_objects_, false) << '\n'; // For loop iterates over elements string i = tmp("_i"); indent(out) << "for (int " << i << " = 0; " << i << " < " << obj << ".size" << "; " - << "++" << i << ")" << endl; + << "++" << i << ")" << '\n'; scope_up(out); @@ -4338,22 +4357,22 @@ void t_java_generator::generate_deserialize_map_element(ostream& out, generate_deserialize_field(out, &fval, "", has_metadata); if (get_true_type(fkey.get_type())->is_enum()) { - indent(out) << "if (" << key << " != null)" << endl; + indent(out) << "if (" << key << " != null)" << '\n'; scope_up(out); } - indent(out) << prefix << ".put(" << key << ", " << val << ");" << endl; + indent(out) << prefix << ".put(" << key << ", " << val << ");" << '\n'; if (get_true_type(fkey.get_type())->is_enum()) { scope_down(out); } if (reuse_objects_ && !get_true_type(fkey.get_type())->is_base_type()) { - indent(out) << key << " = null;" << endl; + indent(out) << key << " = null;" << '\n'; } if (reuse_objects_ && !get_true_type(fval.get_type())->is_base_type()) { - indent(out) << val << " = null;" << endl; + indent(out) << val << " = null;" << '\n'; } } @@ -4368,30 +4387,30 @@ void t_java_generator::generate_deserialize_set_element(ostream& out, string elem = tmp("_elem"); t_field felem(tset->get_elem_type(), elem); - indent(out) << declare_field(&felem, reuse_objects_, false) << endl; + indent(out) << declare_field(&felem, reuse_objects_, false) << '\n'; // For loop iterates over elements string i = tmp("_i"); indent(out) << "for (int " << i << " = 0; " << i << " < " << obj << ".size" << "; " - << "++" << i << ")" << endl; + << "++" << i << ")" << '\n'; scope_up(out); generate_deserialize_field(out, &felem, "", has_metadata); if (get_true_type(felem.get_type())->is_enum()) { - indent(out) << "if (" << elem << " != null)" << endl; + indent(out) << "if (" << elem << " != null)" << '\n'; scope_up(out); } - indent(out) << prefix << ".add(" << elem << ");" << endl; + indent(out) << prefix << ".add(" << elem << ");" << '\n'; if (get_true_type(felem.get_type())->is_enum()) { scope_down(out); } if (reuse_objects_ && !get_true_type(felem.get_type())->is_base_type()) { - indent(out) << elem << " = null;" << endl; + indent(out) << elem << " = null;" << '\n'; } } @@ -4406,30 +4425,30 @@ void t_java_generator::generate_deserialize_list_element(ostream& out, string elem = tmp("_elem"); t_field felem(tlist->get_elem_type(), elem); - indent(out) << declare_field(&felem, reuse_objects_, false) << endl; + indent(out) << declare_field(&felem, reuse_objects_, false) << '\n'; // For loop iterates over elements string i = tmp("_i"); indent(out) << "for (int " << i << " = 0; " << i << " < " << obj << ".size" << "; " - << "++" << i << ")" << endl; + << "++" << i << ")" << '\n'; scope_up(out); generate_deserialize_field(out, &felem, "", has_metadata); if (get_true_type(felem.get_type())->is_enum()) { - indent(out) << "if (" << elem << " != null)" << endl; + indent(out) << "if (" << elem << " != null)" << '\n'; scope_up(out); } - indent(out) << prefix << ".add(" << elem << ");" << endl; + indent(out) << prefix << ".add(" << elem << ");" << '\n'; if (get_true_type(felem.get_type())->is_enum()) { scope_down(out); } if (reuse_objects_ && !get_true_type(felem.get_type())->is_base_type()) { - indent(out) << elem << " = null;" << endl; + indent(out) << elem << " = null;" << '\n'; } } @@ -4455,7 +4474,7 @@ void t_java_generator::generate_serialize_field(ostream& out, } else if (type->is_container()) { generate_serialize_container(out, type, prefix + make_valid_java_identifier(tfield->get_name()) + postfix, has_metadata); } else if (type->is_enum()) { - indent(out) << "oprot.writeI32(" << prefix + make_valid_java_identifier(tfield->get_name()) + postfix << ".getValue());" << endl; + indent(out) << "oprot.writeI32(" << prefix + make_valid_java_identifier(tfield->get_name()) + postfix << ".getValue());" << '\n'; } else if (type->is_base_type()) { string name = prefix + make_valid_java_identifier(tfield->get_name()) + postfix; indent(out) << "oprot."; @@ -4500,7 +4519,7 @@ void t_java_generator::generate_serialize_field(ostream& out, } else if (type->is_enum()) { out << "writeI32(struct." << name << ");"; } - out << endl; + out << '\n'; } else { printf("DO NOT KNOW HOW TO SERIALIZE FIELD '%s%s%s' TYPE '%s'\n", prefix.c_str(), tfield->get_name().c_str(), postfix.c_str(), type_name(type).c_str()); @@ -4515,7 +4534,7 @@ void t_java_generator::generate_serialize_field(ostream& out, */ void t_java_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix) { (void)tstruct; - out << indent() << prefix << ".write(oprot);" << endl; + out << indent() << prefix << ".write(oprot);" << '\n'; } /** @@ -4535,18 +4554,18 @@ void t_java_generator::generate_serialize_container(ostream& out, indent(out) << "oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(" << type_to_enum(((t_map*)ttype)->get_key_type()) << ", " << type_to_enum(((t_map*)ttype)->get_val_type()) << ", " << prefix << ".size()));" - << endl; + << '\n'; } else if (ttype->is_set()) { indent(out) << "oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(" << type_to_enum(((t_set*)ttype)->get_elem_type()) << ", " << prefix - << ".size()));" << endl; + << ".size()));" << '\n'; } else if (ttype->is_list()) { indent(out) << "oprot.writeListBegin(new org.apache.thrift.protocol.TList(" << type_to_enum(((t_list*)ttype)->get_elem_type()) << ", " << prefix - << ".size()));" << endl; + << ".size()));" << '\n'; } } else { - indent(out) << "oprot.writeI32(" << prefix << ".size());" << endl; + indent(out) << "oprot.writeI32(" << prefix << ".size());" << '\n'; } string iter = tmp("_iter"); @@ -4563,7 +4582,7 @@ void t_java_generator::generate_serialize_container(ostream& out, << prefix << ")"; } - out << endl; + out << '\n'; scope_up(out); if (ttype->is_map()) { generate_serialize_map_element(out, (t_map*)ttype, iter, prefix, has_metadata); @@ -4576,11 +4595,11 @@ void t_java_generator::generate_serialize_container(ostream& out, if (has_metadata) { if (ttype->is_map()) { - indent(out) << "oprot.writeMapEnd();" << endl; + indent(out) << "oprot.writeMapEnd();" << '\n'; } else if (ttype->is_set()) { - indent(out) << "oprot.writeSetEnd();" << endl; + indent(out) << "oprot.writeSetEnd();" << '\n'; } else if (ttype->is_list()) { - indent(out) << "oprot.writeListEnd();" << endl; + indent(out) << "oprot.writeListEnd();" << '\n'; } } @@ -5115,7 +5134,7 @@ void t_java_generator::generate_deep_copy_container(ostream& out, // deep copy of base types can be done much more efficiently than iterating over all the // elements manually indent(out) << type_name(type, true, false) << " " << result_name << " = new " - << type_name(container, false, true) << "(" << source_name << ");" << endl; + << type_name(container, false, true) << "(" << source_name << ");" << '\n'; return; } @@ -5130,10 +5149,10 @@ void t_java_generator::generate_deep_copy_container(ostream& out, if (is_enum_set(container)) { indent(out) << type_name(type, true, false) << " " << result_name << " = " << type_name(container, false, true, true) << ".noneOf(" << constructor_args << ");" - << endl; + << '\n'; } else { indent(out) << type_name(type, true, false) << " " << result_name << " = new " - << type_name(container, false, true) << "(" << constructor_args << ");" << endl; + << type_name(container, false, true) << "(" << constructor_args << ");" << '\n'; } std::string iterator_element_name = source_name_p1 + "_element"; @@ -5145,17 +5164,17 @@ void t_java_generator::generate_deep_copy_container(ostream& out, indent(out) << "for (java.util.Map.Entry<" << type_name(key_type, true, false) << ", " << type_name(val_type, true, false) << "> " << iterator_element_name << " : " - << source_name << ".entrySet()) {" << endl; + << source_name << ".entrySet()) {" << '\n'; indent_up(); - out << endl; + out << '\n'; indent(out) << type_name(key_type, true, false) << " " << iterator_element_name - << "_key = " << iterator_element_name << ".getKey();" << endl; + << "_key = " << iterator_element_name << ".getKey();" << '\n'; indent(out) << type_name(val_type, true, false) << " " << iterator_element_name - << "_value = " << iterator_element_name << ".getValue();" << endl; + << "_value = " << iterator_element_name << ".getValue();" << '\n'; - out << endl; + out << '\n'; if (key_type->is_container()) { generate_deep_copy_container(out, iterator_element_name + "_key", "", @@ -5164,10 +5183,10 @@ void t_java_generator::generate_deep_copy_container(ostream& out, indent(out) << type_name(key_type, true, false) << " " << result_element_name << "_key = "; generate_deep_copy_non_container(out, iterator_element_name + "_key", result_element_name + "_key", key_type); - out << ";" << endl; + out << ";" << '\n'; } - out << endl; + out << '\n'; if (val_type->is_container()) { generate_deep_copy_container(out, iterator_element_name + "_value", "", @@ -5176,16 +5195,16 @@ void t_java_generator::generate_deep_copy_container(ostream& out, indent(out) << type_name(val_type, true, false) << " " << result_element_name << "_value = "; generate_deep_copy_non_container(out, iterator_element_name + "_value", result_element_name + "_value", val_type); - out << ";" << endl; + out << ";" << '\n'; } - out << endl; + out << '\n'; indent(out) << result_name << ".put(" << result_element_name << "_key, " << result_element_name - << "_value);" << endl; + << "_value);" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } else { t_type* elem_type; @@ -5197,32 +5216,32 @@ void t_java_generator::generate_deep_copy_container(ostream& out, } indent(out) << "for (" << type_name(elem_type, true, false) << " " << iterator_element_name - << " : " << source_name << ") {" << endl; + << " : " << source_name << ") {" << '\n'; indent_up(); if (elem_type->is_container()) { // recursive deep copy generate_deep_copy_container(out, iterator_element_name, "", result_element_name, elem_type); - indent(out) << result_name << ".add(" << result_element_name << ");" << endl; + indent(out) << result_name << ".add(" << result_element_name << ");" << '\n'; } else { // iterative copy if (elem_type->is_binary()) { indent(out) << "java.nio.ByteBuffer temp_binary_element = "; generate_deep_copy_non_container(out, iterator_element_name, "temp_binary_element", elem_type); - out << ";" << endl; - indent(out) << result_name << ".add(temp_binary_element);" << endl; + out << ";" << '\n'; + indent(out) << result_name << ".add(temp_binary_element);" << '\n'; } else { indent(out) << result_name << ".add("; generate_deep_copy_non_container(out, iterator_element_name, result_name, elem_type); - out << ");" << endl; + out << ");" << '\n'; } } indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } } @@ -5259,14 +5278,14 @@ std::string t_java_generator::generate_isset_check(std::string field_name) { void t_java_generator::generate_isset_set(ostream& out, t_field* field, string prefix) { if (!type_can_be_null(field->get_type())) { indent(out) << prefix << "set" << get_cap_name(field->get_name()) << get_cap_name("isSet") - << "(true);" << endl; + << "(true);" << '\n'; } } void t_java_generator::generate_struct_desc(ostream& out, t_struct* tstruct) { indent(out) << "private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new " "org.apache.thrift.protocol.TStruct(\"" - << tstruct->get_name() << "\");" << endl; + << tstruct->get_name() << "\");" << '\n'; } void t_java_generator::generate_field_descs(ostream& out, t_struct* tstruct) { @@ -5278,24 +5297,24 @@ void t_java_generator::generate_field_descs(ostream& out, t_struct* tstruct) { << constant_name((*m_iter)->get_name()) << "_FIELD_DESC = new org.apache.thrift.protocol.TField(\"" << (*m_iter)->get_name() << "\", " << type_to_enum((*m_iter)->get_type()) << ", " - << "(short)" << (*m_iter)->get_key() << ");" << endl; + << "(short)" << (*m_iter)->get_key() << ");" << '\n'; } } void t_java_generator::generate_scheme_map(ostream& out, t_struct* tstruct) { indent(out) << "private static final org.apache.thrift.scheme.SchemeFactory " "STANDARD_SCHEME_FACTORY = new " - << tstruct->get_name() << "StandardSchemeFactory();" << endl; + << tstruct->get_name() << "StandardSchemeFactory();" << '\n'; indent(out) << "private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new " - << tstruct->get_name() << "TupleSchemeFactory();" << endl; + << tstruct->get_name() << "TupleSchemeFactory();" << '\n'; } void t_java_generator::generate_field_name_constants(ostream& out, t_struct* tstruct) { indent(out) << "/** The set of fields this struct contains, along with convenience methods for " "finding and manipulating them. */" - << endl; - indent(out) << "public enum _Fields implements org.apache.thrift.TFieldIdEnum {" << endl; + << '\n'; + indent(out) << "public enum _Fields implements org.apache.thrift.TFieldIdEnum {" << '\n'; indent_up(); bool first = true; @@ -5303,7 +5322,7 @@ void t_java_generator::generate_field_name_constants(ostream& out, t_struct* tst vector::const_iterator m_iter; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { if (!first) { - out << "," << endl; + out << "," << '\n'; } first = false; generate_java_doc(out, *m_iter); @@ -5311,87 +5330,87 @@ void t_java_generator::generate_field_name_constants(ostream& out, t_struct* tst << ", \"" << (*m_iter)->get_name() << "\")"; } - out << ";" << endl << endl; + out << ";" << '\n' << '\n'; indent(out) << "private static final java.util.Map byName = new " "java.util.HashMap();" - << endl; - out << endl; + << '\n'; + out << '\n'; - indent(out) << "static {" << endl; - indent(out) << " for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {" << endl; - indent(out) << " byName.put(field.getFieldName(), field);" << endl; - indent(out) << " }" << endl; - indent(out) << "}" << endl << endl; + indent(out) << "static {" << '\n'; + indent(out) << " for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {" << '\n'; + indent(out) << " byName.put(field.getFieldName(), field);" << '\n'; + indent(out) << " }" << '\n'; + indent(out) << "}" << '\n' << '\n'; - indent(out) << "/**" << endl; + indent(out) << "/**" << '\n'; indent(out) << " * Find the _Fields constant that matches fieldId, or null if its not found." - << endl; - indent(out) << " */" << endl; - indent(out) << java_nullable_annotation() << endl; - indent(out) << "public static _Fields findByThriftId(int fieldId) {" << endl; + << '\n'; + indent(out) << " */" << '\n'; + indent(out) << java_nullable_annotation() << '\n'; + indent(out) << "public static _Fields findByThriftId(int fieldId) {" << '\n'; indent_up(); - indent(out) << "switch(fieldId) {" << endl; + indent(out) << "switch(fieldId) {" << '\n'; indent_up(); for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { indent(out) << "case " << (*m_iter)->get_key() << ": // " - << constant_name((*m_iter)->get_name()) << endl; - indent(out) << " return " << constant_name((*m_iter)->get_name()) << ";" << endl; + << constant_name((*m_iter)->get_name()) << '\n'; + indent(out) << " return " << constant_name((*m_iter)->get_name()) << ";" << '\n'; } - indent(out) << "default:" << endl; - indent(out) << " return null;" << endl; + indent(out) << "default:" << '\n'; + indent(out) << " return null;" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; - - indent(out) << "/**" << endl; - indent(out) << " * Find the _Fields constant that matches fieldId, throwing an exception" << endl; - indent(out) << " * if it is not found." << endl; - indent(out) << " */" << endl; - indent(out) << "public static _Fields findByThriftIdOrThrow(int fieldId) {" << endl; - indent(out) << " _Fields fields = findByThriftId(fieldId);" << endl; + indent(out) << "}" << '\n' << '\n'; + + indent(out) << "/**" << '\n'; + indent(out) << " * Find the _Fields constant that matches fieldId, throwing an exception" << '\n'; + indent(out) << " * if it is not found." << '\n'; + indent(out) << " */" << '\n'; + indent(out) << "public static _Fields findByThriftIdOrThrow(int fieldId) {" << '\n'; + indent(out) << " _Fields fields = findByThriftId(fieldId);" << '\n'; indent(out) << " if (fields == null) throw new java.lang.IllegalArgumentException(\"Field \" + " "fieldId + " "\" doesn't exist!\");" - << endl; - indent(out) << " return fields;" << endl; - indent(out) << "}" << endl << endl; + << '\n'; + indent(out) << " return fields;" << '\n'; + indent(out) << "}" << '\n' << '\n'; - indent(out) << "/**" << endl; + indent(out) << "/**" << '\n'; indent(out) << " * Find the _Fields constant that matches name, or null if its not found." - << endl; - indent(out) << " */" << endl; - indent(out) << java_nullable_annotation() << endl; - indent(out) << "public static _Fields findByName(java.lang.String name) {" << endl; - indent(out) << " return byName.get(name);" << endl; - indent(out) << "}" << endl << endl; - - indent(out) << "private final short _thriftId;" << endl; - indent(out) << "private final java.lang.String _fieldName;" << endl << endl; - - indent(out) << "_Fields(short thriftId, java.lang.String fieldName) {" << endl; - indent(out) << " _thriftId = thriftId;" << endl; - indent(out) << " _fieldName = fieldName;" << endl; - indent(out) << "}" << endl << endl; - - indent(out) << java_override_annotation() << endl; - indent(out) << "public short getThriftFieldId() {" << endl; - indent(out) << " return _thriftId;" << endl; - indent(out) << "}" << endl << endl; - - indent(out) << java_override_annotation() << endl; - indent(out) << "public java.lang.String getFieldName() {" << endl; - indent(out) << " return _fieldName;" << endl; - indent(out) << "}" << endl; + << '\n'; + indent(out) << " */" << '\n'; + indent(out) << java_nullable_annotation() << '\n'; + indent(out) << "public static _Fields findByName(java.lang.String name) {" << '\n'; + indent(out) << " return byName.get(name);" << '\n'; + indent(out) << "}" << '\n' << '\n'; + + indent(out) << "private final short _thriftId;" << '\n'; + indent(out) << "private final java.lang.String _fieldName;" << '\n' << '\n'; + + indent(out) << "_Fields(short thriftId, java.lang.String fieldName) {" << '\n'; + indent(out) << " _thriftId = thriftId;" << '\n'; + indent(out) << " _fieldName = fieldName;" << '\n'; + indent(out) << "}" << '\n' << '\n'; + + indent(out) << java_override_annotation() << '\n'; + indent(out) << "public short getThriftFieldId() {" << '\n'; + indent(out) << " return _thriftId;" << '\n'; + indent(out) << "}" << '\n' << '\n'; + + indent(out) << java_override_annotation() << '\n'; + indent(out) << "public java.lang.String getFieldName() {" << '\n'; + indent(out) << " return _fieldName;" << '\n'; + indent(out) << "}" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } t_java_generator::isset_type t_java_generator::needs_isset(t_struct* tstruct, @@ -5425,8 +5444,8 @@ t_java_generator::isset_type t_java_generator::needs_isset(t_struct* tstruct, } void t_java_generator::generate_java_struct_clear(std::ostream& out, t_struct* tstruct) { - indent(out) << java_override_annotation() << endl; - indent(out) << "public void clear() {" << endl; + indent(out) << java_override_annotation() << '\n'; + indent(out) << "public void clear() {" << '\n'; indent_up(); for (auto field : tstruct->get_members()) { @@ -5439,13 +5458,13 @@ void t_java_generator::generate_java_struct_clear(std::ostream& out, t_struct* t if (type_can_be_null(t)) { if (reuse_objects_ && (t->is_container() || t->is_struct())) { - indent(out) << "if (this." << make_valid_java_identifier(field->get_name()) << " != null) {" << endl; + indent(out) << "if (this." << make_valid_java_identifier(field->get_name()) << " != null) {" << '\n'; indent_up(); - indent(out) << "this." << make_valid_java_identifier(field->get_name()) << ".clear();" << endl; + indent(out) << "this." << make_valid_java_identifier(field->get_name()) << ".clear();" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } else { - indent(out) << "this." << make_valid_java_identifier(field->get_name()) << " = null;" << endl; + indent(out) << "this." << make_valid_java_identifier(field->get_name()) << " = null;" << '\n'; } continue; } @@ -5453,7 +5472,7 @@ void t_java_generator::generate_java_struct_clear(std::ostream& out, t_struct* t // must be a base type // means it also needs to be explicitly unset indent(out) << "set" << get_cap_name(field->get_name()) << get_cap_name("isSet") << "(false);" - << endl; + << '\n'; t_base_type* base_type = (t_base_type*)t; switch (base_type->get_base()) { @@ -5461,13 +5480,13 @@ void t_java_generator::generate_java_struct_clear(std::ostream& out, t_struct* t case t_base_type::TYPE_I16: case t_base_type::TYPE_I32: case t_base_type::TYPE_I64: - indent(out) << "this." << make_valid_java_identifier(field->get_name()) << " = 0;" << endl; + indent(out) << "this." << make_valid_java_identifier(field->get_name()) << " = 0;" << '\n'; break; case t_base_type::TYPE_DOUBLE: - indent(out) << "this." << make_valid_java_identifier(field->get_name()) << " = 0.0;" << endl; + indent(out) << "this." << make_valid_java_identifier(field->get_name()) << " = 0.0;" << '\n'; break; case t_base_type::TYPE_BOOL: - indent(out) << "this." << make_valid_java_identifier(field->get_name()) << " = false;" << endl; + indent(out) << "this." << make_valid_java_identifier(field->get_name()) << " = false;" << '\n'; break; default: throw "unsupported type: " + base_type->get_name() + " for field " + field->get_name(); @@ -5475,7 +5494,7 @@ void t_java_generator::generate_java_struct_clear(std::ostream& out, t_struct* t } indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } // generates java method to serialize (in the Java sense) the object @@ -5483,24 +5502,24 @@ void t_java_generator::generate_java_struct_write_object(ostream& out, t_struct* (void)tstruct; indent(out) << "private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {" - << endl; - indent(out) << " try {" << endl; + << '\n'; + indent(out) << " try {" << '\n'; indent(out) << " write(new org.apache.thrift.protocol.TCompactProtocol(new " "org.apache.thrift.transport.TIOStreamTransport(out)));" - << endl; - indent(out) << " } catch (org.apache.thrift.TException te) {" << endl; + << '\n'; + indent(out) << " } catch (org.apache.thrift.TException te) {" << '\n'; indent(out) << " throw new java.io.IOException(te" << (android_legacy_ ? ".getMessage()" : "") - << ");" << endl; - indent(out) << " }" << endl; - indent(out) << "}" << endl << endl; + << ");" << '\n'; + indent(out) << " }" << '\n'; + indent(out) << "}" << '\n' << '\n'; } // generates java method to serialize (in the Java sense) the object void t_java_generator::generate_java_struct_read_object(ostream& out, t_struct* tstruct) { indent(out) << "private void readObject(java.io.ObjectInputStream in) throws " "java.io.IOException, java.lang.ClassNotFoundException {" - << endl; - indent(out) << " try {" << endl; + << '\n'; + indent(out) << " try {" << '\n'; if (!tstruct->is_union()) { switch (needs_isset(tstruct)) { case ISSET_NONE: @@ -5508,174 +5527,174 @@ void t_java_generator::generate_java_struct_read_object(ostream& out, t_struct* case ISSET_PRIMITIVE: indent(out) << " // it doesn't seem like you should have to do this, but java " "serialization is wacky, and doesn't call the default constructor." - << endl; - indent(out) << " __isset_bitfield = 0;" << endl; + << '\n'; + indent(out) << " __isset_bitfield = 0;" << '\n'; break; case ISSET_BITSET: indent(out) << " // it doesn't seem like you should have to do this, but java " "serialization is wacky, and doesn't call the default constructor." - << endl; - indent(out) << " __isset_bit_vector = new java.util.BitSet(1);" << endl; + << '\n'; + indent(out) << " __isset_bit_vector = new java.util.BitSet(1);" << '\n'; break; } } indent(out) << " read(new org.apache.thrift.protocol.TCompactProtocol(new " "org.apache.thrift.transport.TIOStreamTransport(in)));" - << endl; - indent(out) << " } catch (org.apache.thrift.TException te) {" << endl; + << '\n'; + indent(out) << " } catch (org.apache.thrift.TException te) {" << '\n'; indent(out) << " throw new java.io.IOException(te" << (android_legacy_ ? ".getMessage()" : "") - << ");" << endl; - indent(out) << " }" << endl; - indent(out) << "}" << endl << endl; + << ");" << '\n'; + indent(out) << " }" << '\n'; + indent(out) << "}" << '\n' << '\n'; } void t_java_generator::generate_standard_reader(ostream& out, t_struct* tstruct) { - indent(out) << java_override_annotation() << endl; + indent(out) << java_override_annotation() << '\n'; indent(out) << "public void read(org.apache.thrift.protocol.TProtocol iprot, " - << make_valid_java_identifier(tstruct->get_name()) << " struct) throws org.apache.thrift.TException {" << endl; + << make_valid_java_identifier(tstruct->get_name()) << " struct) throws org.apache.thrift.TException {" << '\n'; indent_up(); const vector& fields = tstruct->get_members(); vector::const_iterator f_iter; // Declare stack tmp variables and read struct header - out << indent() << "org.apache.thrift.protocol.TField schemeField;" << endl - << indent() << "iprot.readStructBegin();" << endl; + out << indent() << "org.apache.thrift.protocol.TField schemeField;" << '\n' + << indent() << "iprot.readStructBegin();" << '\n'; // Loop over reading in fields - indent(out) << "while (true)" << endl; + indent(out) << "while (true)" << '\n'; scope_up(out); // Read beginning field marker - indent(out) << "schemeField = iprot.readFieldBegin();" << endl; + indent(out) << "schemeField = iprot.readFieldBegin();" << '\n'; // Check for field STOP marker and break - indent(out) << "if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { " << endl; + indent(out) << "if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { " << '\n'; indent_up(); - indent(out) << "break;" << endl; + indent(out) << "break;" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; // Switch statement on the field we are reading - indent(out) << "switch (schemeField.id) {" << endl; + indent(out) << "switch (schemeField.id) {" << '\n'; indent_up(); // Generate deserialization code for known cases for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { indent(out) << "case " << (*f_iter)->get_key() << ": // " - << constant_name((*f_iter)->get_name()) << endl; + << constant_name((*f_iter)->get_name()) << '\n'; indent_up(); indent(out) << "if (schemeField.type == " << type_to_enum((*f_iter)->get_type()) << ") {" - << endl; + << '\n'; indent_up(); generate_deserialize_field(out, *f_iter, "struct.", true); indent(out) << "struct." << "set" << get_cap_name((*f_iter)->get_name()) << get_cap_name("isSet") - << "(true);" << endl; + << "(true);" << '\n'; indent_down(); - out << indent() << "} else { " << endl + out << indent() << "} else { " << '\n' << indent() << " org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);" - << endl - << indent() << "}" << endl - << indent() << "break;" << endl; + << '\n' + << indent() << "}" << '\n' + << indent() << "break;" << '\n'; indent_down(); } - indent(out) << "default:" << endl; + indent(out) << "default:" << '\n'; indent(out) << " org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);" - << endl; + << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; // Read field end marker - indent(out) << "iprot.readFieldEnd();" << endl; + indent(out) << "iprot.readFieldEnd();" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; - out << indent() << "iprot.readStructEnd();" << endl; + out << indent() << "iprot.readStructEnd();" << '\n'; // in non-beans style, check for required fields of primitive type // (which can be checked here but not in the general validate method) if (!bean_style_) { - out << endl + out << '\n' << indent() << "// check for required fields of primitive type, which can't be " "checked in the validate method" - << endl; + << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if ((*f_iter)->get_req() == t_field::T_REQUIRED && !type_can_be_null((*f_iter)->get_type())) { - out << indent() << "if (!struct." << generate_isset_check(*f_iter) << ") {" << endl + out << indent() << "if (!struct." << generate_isset_check(*f_iter) << ") {" << '\n' << indent() << " throw new org.apache.thrift.protocol.TProtocolException(\"Required field '" << (*f_iter)->get_name() - << "' was not found in serialized data! Struct: \" + toString());" << endl - << indent() << "}" << endl; + << "' was not found in serialized data! Struct: \" + toString());" << '\n' + << indent() << "}" << '\n'; } } } // performs various checks (e.g. check that all required fields are set) - indent(out) << "struct.validate();" << endl; + indent(out) << "struct.validate();" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } void t_java_generator::generate_standard_writer(ostream& out, t_struct* tstruct, bool is_result) { indent_up(); - indent(out) << java_override_annotation() << endl; + indent(out) << java_override_annotation() << '\n'; indent(out) << "public void write(org.apache.thrift.protocol.TProtocol oprot, " - << make_valid_java_identifier(tstruct->get_name()) << " struct) throws org.apache.thrift.TException {" << endl; + << make_valid_java_identifier(tstruct->get_name()) << " struct) throws org.apache.thrift.TException {" << '\n'; indent_up(); const vector& fields = tstruct->get_sorted_members(); vector::const_iterator f_iter; // performs various checks (e.g. check that all required fields are set) - indent(out) << "struct.validate();" << endl << endl; + indent(out) << "struct.validate();" << '\n' << '\n'; - indent(out) << "oprot.writeStructBegin(STRUCT_DESC);" << endl; + indent(out) << "oprot.writeStructBegin(STRUCT_DESC);" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { bool null_allowed = type_can_be_null((*f_iter)->get_type()); if (null_allowed) { - out << indent() << "if (struct." << make_valid_java_identifier((*f_iter)->get_name()) << " != null) {" << endl; + out << indent() << "if (struct." << make_valid_java_identifier((*f_iter)->get_name()) << " != null) {" << '\n'; indent_up(); } bool optional = ((*f_iter)->get_req() == t_field::T_OPTIONAL) || (is_result && !null_allowed); if (optional) { indent(out) << "if (" - << "struct." << generate_isset_check((*f_iter)) << ") {" << endl; + << "struct." << generate_isset_check((*f_iter)) << ") {" << '\n'; indent_up(); } indent(out) << "oprot.writeFieldBegin(" << constant_name((*f_iter)->get_name()) - << "_FIELD_DESC);" << endl; + << "_FIELD_DESC);" << '\n'; // Write field contents generate_serialize_field(out, *f_iter, "struct.", "", true); // Write field closer - indent(out) << "oprot.writeFieldEnd();" << endl; + indent(out) << "oprot.writeFieldEnd();" << '\n'; if (optional) { indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } if (null_allowed) { indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } } // Write the struct map - out << indent() << "oprot.writeFieldStop();" << endl - << indent() << "oprot.writeStructEnd();" << endl; + out << indent() << "oprot.writeFieldStop();" << '\n' + << indent() << "oprot.writeStructEnd();" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; indent_down(); } @@ -5684,38 +5703,38 @@ void t_java_generator::generate_java_struct_standard_scheme(ostream& out, bool is_result) { indent(out) << "private static class " << tstruct->get_name() << "StandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {" - << endl; + << '\n'; indent_up(); - indent(out) << java_override_annotation() << endl; - indent(out) << "public " << tstruct->get_name() << "StandardScheme getScheme() {" << endl; + indent(out) << java_override_annotation() << '\n'; + indent(out) << "public " << tstruct->get_name() << "StandardScheme getScheme() {" << '\n'; indent_up(); - indent(out) << "return new " << tstruct->get_name() << "StandardScheme();" << endl; + indent(out) << "return new " << tstruct->get_name() << "StandardScheme();" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; out << indent() << "private static class " << tstruct->get_name() << "StandardScheme extends org.apache.thrift.scheme.StandardScheme<" << make_valid_java_identifier(tstruct->get_name()) - << "> {" << endl - << endl; + << "> {" << '\n' + << '\n'; indent_up(); generate_standard_reader(out, tstruct); indent_down(); - out << endl; + out << '\n'; generate_standard_writer(out, tstruct, is_result); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } void t_java_generator::generate_java_struct_tuple_reader(ostream& out, t_struct* tstruct) { - indent(out) << java_override_annotation() << endl; + indent(out) << java_override_annotation() << '\n'; indent(out) << "public void read(org.apache.thrift.protocol.TProtocol prot, " - << make_valid_java_identifier(tstruct->get_name()) << " struct) throws org.apache.thrift.TException {" << endl; + << make_valid_java_identifier(tstruct->get_name()) << " struct) throws org.apache.thrift.TException {" << '\n'; indent_up(); indent(out) << "org.apache.thrift.protocol.TTupleProtocol iprot = " "(org.apache.thrift.protocol.TTupleProtocol) prot;" - << endl; + << '\n'; int optional_count = 0; const vector& fields = tstruct->get_members(); vector::const_iterator f_iter; @@ -5727,39 +5746,39 @@ void t_java_generator::generate_java_struct_tuple_reader(ostream& out, t_struct* if ((*f_iter)->get_req() == t_field::T_REQUIRED) { generate_deserialize_field(out, (*f_iter), "struct.", false); indent(out) << "struct.set" << get_cap_name((*f_iter)->get_name()) << get_cap_name("isSet") - << "(true);" << endl; + << "(true);" << '\n'; } } if (optional_count > 0) { indent(out) << "java.util.BitSet incoming = iprot.readBitSet(" << optional_count << ");" - << endl; + << '\n'; int i = 0; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if ((*f_iter)->get_req() == t_field::T_OPTIONAL || (*f_iter)->get_req() == t_field::T_OPT_IN_REQ_OUT) { - indent(out) << "if (incoming.get(" << i << ")) {" << endl; + indent(out) << "if (incoming.get(" << i << ")) {" << '\n'; indent_up(); generate_deserialize_field(out, (*f_iter), "struct.", false); indent(out) << "struct.set" << get_cap_name((*f_iter)->get_name()) << get_cap_name("isSet") - << "(true);" << endl; + << "(true);" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; i++; } } } indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } void t_java_generator::generate_java_struct_tuple_writer(ostream& out, t_struct* tstruct) { - indent(out) << java_override_annotation() << endl; + indent(out) << java_override_annotation() << '\n'; indent(out) << "public void write(org.apache.thrift.protocol.TProtocol prot, " - << make_valid_java_identifier(tstruct->get_name()) << " struct) throws org.apache.thrift.TException {" << endl; + << make_valid_java_identifier(tstruct->get_name()) << " struct) throws org.apache.thrift.TException {" << '\n'; indent_up(); indent(out) << "org.apache.thrift.protocol.TTupleProtocol oprot = " "(org.apache.thrift.protocol.TTupleProtocol) prot;" - << endl; + << '\n'; const vector& fields = tstruct->get_members(); vector::const_iterator f_iter; @@ -5776,70 +5795,70 @@ void t_java_generator::generate_java_struct_tuple_writer(ostream& out, t_struct* } } if (has_optional) { - indent(out) << "java.util.BitSet optionals = new java.util.BitSet();" << endl; + indent(out) << "java.util.BitSet optionals = new java.util.BitSet();" << '\n'; int i = 0; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if ((*f_iter)->get_req() == t_field::T_OPTIONAL || (*f_iter)->get_req() == t_field::T_OPT_IN_REQ_OUT) { - indent(out) << "if (struct." << generate_isset_check((*f_iter)) << ") {" << endl; + indent(out) << "if (struct." << generate_isset_check((*f_iter)) << ") {" << '\n'; indent_up(); - indent(out) << "optionals.set(" << i << ");" << endl; + indent(out) << "optionals.set(" << i << ");" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; i++; } } - indent(out) << "oprot.writeBitSet(optionals, " << optional_count << ");" << endl; + indent(out) << "oprot.writeBitSet(optionals, " << optional_count << ");" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if ((*f_iter)->get_req() == t_field::T_OPTIONAL || (*f_iter)->get_req() == t_field::T_OPT_IN_REQ_OUT) { - indent(out) << "if (struct." << generate_isset_check(*f_iter) << ") {" << endl; + indent(out) << "if (struct." << generate_isset_check(*f_iter) << ") {" << '\n'; indent_up(); generate_serialize_field(out, (*f_iter), "struct.", "", false); indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } } } indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } void t_java_generator::generate_java_struct_tuple_scheme(ostream& out, t_struct* tstruct) { indent(out) << "private static class " << tstruct->get_name() - << "TupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {" << endl; + << "TupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {" << '\n'; indent_up(); - indent(out) << java_override_annotation() << endl; - indent(out) << "public " << tstruct->get_name() << "TupleScheme getScheme() {" << endl; + indent(out) << java_override_annotation() << '\n'; + indent(out) << "public " << tstruct->get_name() << "TupleScheme getScheme() {" << '\n'; indent_up(); - indent(out) << "return new " << tstruct->get_name() << "TupleScheme();" << endl; + indent(out) << "return new " << tstruct->get_name() << "TupleScheme();" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; out << indent() << "private static class " << tstruct->get_name() << "TupleScheme extends org.apache.thrift.scheme.TupleScheme<" << make_valid_java_identifier(tstruct->get_name()) << "> {" - << endl - << endl; + << '\n' + << '\n'; indent_up(); generate_java_struct_tuple_writer(out, tstruct); - out << endl; + out << '\n'; generate_java_struct_tuple_reader(out, tstruct); indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } void t_java_generator::generate_java_scheme_lookup(ostream& out) { indent(out) << "private static S scheme(" - << "org.apache.thrift.protocol.TProtocol proto) {" << endl; + << "org.apache.thrift.protocol.TProtocol proto) {" << '\n'; indent_up(); indent(out) << "return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) " << "? STANDARD_SCHEME_FACTORY " << ": TUPLE_SCHEME_FACTORY" - << ").getScheme();" << endl; + << ").getScheme();" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } void t_java_generator::generate_javax_generated_annotation(ostream& out) { @@ -5852,11 +5871,11 @@ void t_java_generator::generate_javax_generated_annotation(ostream& out) { } if (undated_generated_annotations_) { - out << ")" << endl; + out << ")" << '\n'; } else { indent(out) << ", date = \"" << (now->tm_year + 1900) << "-" << setfill('0') << setw(2) << (now->tm_mon + 1) << "-" << setfill('0') << setw(2) << now->tm_mday << "\")" - << endl; + << '\n'; } } diff --git a/compiler/cpp/src/thrift/generate/t_javame_generator.cc b/compiler/cpp/src/thrift/generate/t_javame_generator.cc index d8d9056306c..e2c3a395cdc 100644 --- a/compiler/cpp/src/thrift/generate/t_javame_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_javame_generator.cc @@ -37,8 +37,6 @@ using std::string; using std::stringstream; using std::vector; -static const string endl = "\n"; // avoid ostream << std::endl flushes - /** * Java code generator. * @@ -339,7 +337,7 @@ void t_javame_generator::generate_enum(t_enum* tenum) { generate_java_doc(f_enum, tenum); indent(f_enum) << "public class " << tenum->get_name() << " implements org.apache.thrift.TEnum "; scope_up(f_enum); - f_enum << endl; + f_enum << '\n'; vector constants = tenum->get_constants(); vector::iterator c_iter; @@ -347,53 +345,53 @@ void t_javame_generator::generate_enum(t_enum* tenum) { int value = (*c_iter)->get_value(); generate_java_doc(f_enum, *c_iter); indent(f_enum) << "public static final " << tenum->get_name() << " " << (*c_iter)->get_name() - << " = new " << tenum->get_name() << "(" << value << ");" << endl; + << " = new " << tenum->get_name() << "(" << value << ");" << '\n'; } - f_enum << endl; + f_enum << '\n'; // Field for thriftCode - indent(f_enum) << "private final int value;" << endl << endl; + indent(f_enum) << "private final int value;" << '\n' << '\n'; - indent(f_enum) << "private " << tenum->get_name() << "(int value) {" << endl; - indent(f_enum) << " this.value = value;" << endl; - indent(f_enum) << "}" << endl << endl; + indent(f_enum) << "private " << tenum->get_name() << "(int value) {" << '\n'; + indent(f_enum) << " this.value = value;" << '\n'; + indent(f_enum) << "}" << '\n' << '\n'; - indent(f_enum) << "/**" << endl; + indent(f_enum) << "/**" << '\n'; indent(f_enum) << " * Get the integer value of this enum value, as defined in the Thrift IDL." - << endl; - indent(f_enum) << " */" << endl; - indent(f_enum) << "public int getValue() {" << endl; - indent(f_enum) << " return value;" << endl; - indent(f_enum) << "}" << endl << endl; + << '\n'; + indent(f_enum) << " */" << '\n'; + indent(f_enum) << "public int getValue() {" << '\n'; + indent(f_enum) << " return value;" << '\n'; + indent(f_enum) << "}" << '\n' << '\n'; - indent(f_enum) << "/**" << endl; + indent(f_enum) << "/**" << '\n'; indent(f_enum) << " * Find a the enum type by its integer value, as defined in the Thrift IDL." - << endl; - indent(f_enum) << " * @return null if the value is not found." << endl; - indent(f_enum) << " */" << endl; - indent(f_enum) << "public static " + tenum->get_name() + " findByValue(int value) { " << endl; + << '\n'; + indent(f_enum) << " * @return null if the value is not found." << '\n'; + indent(f_enum) << " */" << '\n'; + indent(f_enum) << "public static " + tenum->get_name() + " findByValue(int value) { " << '\n'; indent_up(); - indent(f_enum) << "switch (value) {" << endl; + indent(f_enum) << "switch (value) {" << '\n'; indent_up(); for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) { int value = (*c_iter)->get_value(); - indent(f_enum) << "case " << value << ":" << endl; - indent(f_enum) << " return " << (*c_iter)->get_name() << ";" << endl; + indent(f_enum) << "case " << value << ":" << '\n'; + indent(f_enum) << " return " << (*c_iter)->get_name() << ";" << '\n'; } - indent(f_enum) << "default:" << endl; - indent(f_enum) << " return null;" << endl; + indent(f_enum) << "default:" << '\n'; + indent(f_enum) << " return null;" << '\n'; indent_down(); - indent(f_enum) << "}" << endl; + indent(f_enum) << "}" << '\n'; indent_down(); - indent(f_enum) << "}" << endl; + indent(f_enum) << "}" << '\n'; scope_down(f_enum); @@ -415,7 +413,7 @@ void t_javame_generator::generate_consts(std::vector consts) { // Print header f_consts << autogen_comment() << java_package() << java_type_imports(); - f_consts << "public class " << program_name_ << "Constants {" << endl << endl; + f_consts << "public class " << program_name_ << "Constants {" << '\n' << '\n'; indent_up(); vector::iterator c_iter; for (c_iter = consts.begin(); c_iter != consts.end(); ++c_iter) { @@ -426,7 +424,7 @@ void t_javame_generator::generate_consts(std::vector consts) { false); } indent_down(); - indent(f_consts) << "}" << endl; + indent(f_consts) << "}" << '\n'; f_consts.close(); } @@ -449,17 +447,17 @@ void t_javame_generator::print_const_value(std::ostream& out, } if (type->is_base_type()) { string v2 = render_const_value(out, name, type, value); - out << name << " = " << v2 << ";" << endl << endl; + out << name << " = " << v2 << ";" << '\n' << '\n'; } else if (type->is_enum()) { - out << name << " = " << render_const_value(out, name, type, value) << ";" << endl << endl; + out << name << " = " << render_const_value(out, name, type, value) << ";" << '\n' << '\n'; } else if (type->is_struct() || type->is_xception()) { const vector& fields = ((t_struct*)type)->get_members(); vector::const_iterator f_iter; const map& val = value->get_map(); map::const_iterator v_iter; - out << name << " = new " << type_name(type, false, true) << "();" << endl; + out << name << " = new " << type_name(type, false, true) << "();" << '\n'; if (!in_static) { - indent(out) << "static {" << endl; + indent(out) << "static {" << '\n'; indent_up(); } for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { @@ -475,17 +473,17 @@ void t_javame_generator::print_const_value(std::ostream& out, string val = render_const_value(out, name, field_type, v_iter->second); indent(out) << name << "."; std::string cap_name = get_cap_name(v_iter->first->get_string()); - out << "set" << cap_name << "(" << val << ");" << endl; + out << "set" << cap_name << "(" << val << ");" << '\n'; } if (!in_static) { indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } - out << endl; + out << '\n'; } else if (type->is_map()) { - out << name << " = new " << type_name(type, false, true) << "();" << endl; + out << name << " = new " << type_name(type, false, true) << "();" << '\n'; if (!in_static) { - indent(out) << "static {" << endl; + indent(out) << "static {" << '\n'; indent_up(); } t_type* ktype = ((t_map*)type)->get_key_type(); @@ -496,17 +494,17 @@ void t_javame_generator::print_const_value(std::ostream& out, string key = render_const_value(out, name, ktype, v_iter->first); string val = render_const_value(out, name, vtype, v_iter->second); indent(out) << name << ".put(" << box_type(ktype, key) << ", " << box_type(vtype, val) << ");" - << endl; + << '\n'; } if (!in_static) { indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } - out << endl; + out << '\n'; } else if (type->is_list() || type->is_set()) { - out << name << " = new " << type_name(type, false, true) << "();" << endl; + out << name << " = new " << type_name(type, false, true) << "();" << '\n'; if (!in_static) { - indent(out) << "static {" << endl; + indent(out) << "static {" << '\n'; indent_up(); } t_type* etype; @@ -520,17 +518,17 @@ void t_javame_generator::print_const_value(std::ostream& out, for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { string val = render_const_value(out, name, etype, *v_iter); if (type->is_list()) { - indent(out) << name << ".addElement(" << box_type(etype, val) << ");" << endl; + indent(out) << name << ".addElement(" << box_type(etype, val) << ");" << '\n'; } else { indent(out) << name << ".put(" << box_type(etype, val) << ", " << box_type(etype, val) - << ");" << endl; + << ");" << '\n'; } } if (!in_static) { indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } - out << endl; + out << '\n'; } else { throw "compiler error: no const of type " + type->get_name(); } @@ -673,27 +671,27 @@ void t_javame_generator::generate_java_union(t_struct* tstruct) { generate_struct_desc(f_struct, tstruct); generate_field_descs(f_struct, tstruct); - f_struct << endl; + f_struct << '\n'; generate_union_constructor(f_struct, tstruct); - f_struct << endl; + f_struct << '\n'; generate_union_abstract_methods(f_struct, tstruct); - f_struct << endl; + f_struct << '\n'; generate_union_getters_and_setters(f_struct, tstruct); - f_struct << endl; + f_struct << '\n'; generate_union_comparisons(f_struct, tstruct); - f_struct << endl; + f_struct << '\n'; generate_union_hashcode(f_struct, tstruct); - f_struct << endl; + f_struct << '\n'; scope_down(f_struct); @@ -701,33 +699,33 @@ void t_javame_generator::generate_java_union(t_struct* tstruct) { } void t_javame_generator::generate_union_constructor(ostream& out, t_struct* tstruct) { - indent(out) << "public " << type_name(tstruct) << "() {" << endl; - indent(out) << " super();" << endl; - indent(out) << "}" << endl << endl; + indent(out) << "public " << type_name(tstruct) << "() {" << '\n'; + indent(out) << " super();" << '\n'; + indent(out) << "}" << '\n' << '\n'; - indent(out) << "public " << type_name(tstruct) << "(_Fields setField, Object value) {" << endl; - indent(out) << " super(setField, value);" << endl; - indent(out) << "}" << endl << endl; + indent(out) << "public " << type_name(tstruct) << "(_Fields setField, Object value) {" << '\n'; + indent(out) << " super(setField, value);" << '\n'; + indent(out) << "}" << '\n' << '\n'; indent(out) << "public " << type_name(tstruct) << "(" << type_name(tstruct) << " other) {" - << endl; - indent(out) << " super(other);" << endl; - indent(out) << "}" << endl; + << '\n'; + indent(out) << " super(other);" << '\n'; + indent(out) << "}" << '\n'; - indent(out) << "public " << tstruct->get_name() << " deepCopy() {" << endl; - indent(out) << " return new " << tstruct->get_name() << "(this);" << endl; - indent(out) << "}" << endl << endl; + indent(out) << "public " << tstruct->get_name() << " deepCopy() {" << '\n'; + indent(out) << " return new " << tstruct->get_name() << "(this);" << '\n'; + indent(out) << "}" << '\n' << '\n'; // generate "constructors" for each field const vector& members = tstruct->get_members(); vector::const_iterator m_iter; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { indent(out) << "public static " << type_name(tstruct) << " " << (*m_iter)->get_name() << "(" - << type_name((*m_iter)->get_type()) << " value) {" << endl; - indent(out) << " " << type_name(tstruct) << " x = new " << type_name(tstruct) << "();" << endl; - indent(out) << " x.set" << get_cap_name((*m_iter)->get_name()) << "(value);" << endl; - indent(out) << " return x;" << endl; - indent(out) << "}" << endl << endl; + << type_name((*m_iter)->get_type()) << " value) {" << '\n'; + indent(out) << " " << type_name(tstruct) << " x = new " << type_name(tstruct) << "();" << '\n'; + indent(out) << " x.set" << get_cap_name((*m_iter)->get_name()) << "(value);" << '\n'; + indent(out) << " return x;" << '\n'; + indent(out) << "}" << '\n' << '\n'; } } @@ -740,59 +738,59 @@ void t_javame_generator::generate_union_getters_and_setters(ostream& out, t_stru if (first) { first = false; } else { - out << endl; + out << '\n'; } t_field* field = (*m_iter); generate_java_doc(out, field); indent(out) << "public " << type_name(field->get_type()) << " get" - << get_cap_name(field->get_name()) << "() {" << endl; + << get_cap_name(field->get_name()) << "() {" << '\n'; indent(out) << " if (getSetField() == _Fields." << constant_name(field->get_name()) << ") {" - << endl; + << '\n'; indent(out) << " return (" << type_name(field->get_type(), true) << ")getFieldValue();" - << endl; - indent(out) << " } else {" << endl; + << '\n'; + indent(out) << " } else {" << '\n'; indent(out) << " throw new RuntimeException(\"Cannot get field '" << field->get_name() << "' because union is currently set to \" + getFieldDesc(getSetField()).name);" - << endl; - indent(out) << " }" << endl; - indent(out) << "}" << endl; + << '\n'; + indent(out) << " }" << '\n'; + indent(out) << "}" << '\n'; - out << endl; + out << '\n'; generate_java_doc(out, field); indent(out) << "public void set" << get_cap_name(field->get_name()) << "(" - << type_name(field->get_type()) << " value) {" << endl; + << type_name(field->get_type()) << " value) {" << '\n'; if (type_can_be_null(field->get_type())) { - indent(out) << " if (value == null) throw new NullPointerException();" << endl; + indent(out) << " if (value == null) throw new NullPointerException();" << '\n'; } - indent(out) << " setField_ = _Fields." << constant_name(field->get_name()) << ";" << endl; - indent(out) << " value_ = value;" << endl; - indent(out) << "}" << endl; + indent(out) << " setField_ = _Fields." << constant_name(field->get_name()) << ";" << '\n'; + indent(out) << " value_ = value;" << '\n'; + indent(out) << "}" << '\n'; } } void t_javame_generator::generate_union_abstract_methods(ostream& out, t_struct* tstruct) { generate_check_type(out, tstruct); - out << endl; + out << '\n'; generate_read_value(out, tstruct); - out << endl; + out << '\n'; generate_write_value(out, tstruct); - out << endl; + out << '\n'; generate_get_field_desc(out, tstruct); - out << endl; + out << '\n'; generate_get_struct_desc(out, tstruct); - out << endl; + out << '\n'; } void t_javame_generator::generate_check_type(ostream& out, t_struct* tstruct) { indent(out) << "protected void checkType(_Fields setField, Object value) throws ClassCastException {" - << endl; + << '\n'; indent_up(); - indent(out) << "switch (setField) {" << endl; + indent(out) << "switch (setField) {" << '\n'; indent_up(); const vector& members = tstruct->get_members(); @@ -801,37 +799,37 @@ void t_javame_generator::generate_check_type(ostream& out, t_struct* tstruct) { for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { t_field* field = (*m_iter); - indent(out) << "case " << constant_name(field->get_name()) << ":" << endl; + indent(out) << "case " << constant_name(field->get_name()) << ":" << '\n'; indent(out) << " if (value instanceof " << type_name(field->get_type(), true, false, true) - << ") {" << endl; - indent(out) << " break;" << endl; - indent(out) << " }" << endl; + << ") {" << '\n'; + indent(out) << " break;" << '\n'; + indent(out) << " }" << '\n'; indent(out) << " throw new ClassCastException(\"Was expecting value of type " << type_name(field->get_type(), true, false) << " for field '" << field->get_name() - << "', but got \" + value.getClass().getSimpleName());" << endl; + << "', but got \" + value.getClass().getSimpleName());" << '\n'; // do the real check here } - indent(out) << "default:" << endl; - indent(out) << " throw new IllegalArgumentException(\"Unknown field id \" + setField);" << endl; + indent(out) << "default:" << '\n'; + indent(out) << " throw new IllegalArgumentException(\"Unknown field id \" + setField);" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } void t_javame_generator::generate_read_value(ostream& out, t_struct* tstruct) { indent(out) << "protected Object readValue(TProtocol iprot, TField field) throws TException {" - << endl; + << '\n'; indent_up(); - indent(out) << "_Fields setField = _Fields.findByThriftId(field.id);" << endl; - indent(out) << "if (setField != null) {" << endl; + indent(out) << "_Fields setField = _Fields.findByThriftId(field.id);" << '\n'; + indent(out) << "if (setField != null) {" << '\n'; indent_up(); - indent(out) << "switch (setField) {" << endl; + indent(out) << "switch (setField) {" << '\n'; indent_up(); const vector& members = tstruct->get_members(); @@ -840,48 +838,48 @@ void t_javame_generator::generate_read_value(ostream& out, t_struct* tstruct) { for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { t_field* field = (*m_iter); - indent(out) << "case " << constant_name(field->get_name()) << ":" << endl; + indent(out) << "case " << constant_name(field->get_name()) << ":" << '\n'; indent_up(); indent(out) << "if (field.type == " << constant_name(field->get_name()) << "_FIELD_DESC.type) {" - << endl; + << '\n'; indent_up(); indent(out) << type_name(field->get_type(), true, false) << " " << field->get_name() << ";" - << endl; + << '\n'; generate_deserialize_field(out, field, ""); - indent(out) << "return " << field->get_name() << ";" << endl; + indent(out) << "return " << field->get_name() << ";" << '\n'; indent_down(); - indent(out) << "} else {" << endl; - indent(out) << " TProtocolUtil.skip(iprot, field.type);" << endl; - indent(out) << " return null;" << endl; - indent(out) << "}" << endl; + indent(out) << "} else {" << '\n'; + indent(out) << " TProtocolUtil.skip(iprot, field.type);" << '\n'; + indent(out) << " return null;" << '\n'; + indent(out) << "}" << '\n'; indent_down(); } - indent(out) << "default:" << endl; + indent(out) << "default:" << '\n'; indent(out) << " throw new IllegalStateException(\"setField wasn't null, but didn't match any " - "of the case statements!\");" << endl; + "of the case statements!\");" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; indent_down(); - indent(out) << "} else {" << endl; + indent(out) << "} else {" << '\n'; indent_up(); - indent(out) << "TProtocolUtil.skip(iprot, field.type);" << endl; - indent(out) << "return null;" << endl; + indent(out) << "TProtocolUtil.skip(iprot, field.type);" << '\n'; + indent(out) << "return null;" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } void t_javame_generator::generate_write_value(ostream& out, t_struct* tstruct) { - indent(out) << "protected void writeValue(TProtocol oprot) throws TException {" << endl; + indent(out) << "protected void writeValue(TProtocol oprot) throws TException {" << '\n'; indent_up(); - indent(out) << "switch (setField_) {" << endl; + indent(out) << "switch (setField_) {" << '\n'; indent_up(); const vector& members = tstruct->get_members(); @@ -890,100 +888,100 @@ void t_javame_generator::generate_write_value(ostream& out, t_struct* tstruct) { for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { t_field* field = (*m_iter); - indent(out) << "case " << constant_name(field->get_name()) << ":" << endl; + indent(out) << "case " << constant_name(field->get_name()) << ":" << '\n'; indent_up(); indent(out) << type_name(field->get_type(), true, false) << " " << field->get_name() << " = (" - << type_name(field->get_type(), true, false) << ")value_;" << endl; + << type_name(field->get_type(), true, false) << ")value_;" << '\n'; generate_serialize_field(out, field, ""); - indent(out) << "return;" << endl; + indent(out) << "return;" << '\n'; indent_down(); } - indent(out) << "default:" << endl; + indent(out) << "default:" << '\n'; indent(out) << " throw new IllegalStateException(\"Cannot write union with unknown field \" + " - "setField_);" << endl; + "setField_);" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } void t_javame_generator::generate_get_field_desc(ostream& out, t_struct* tstruct) { - indent(out) << "protected TField getFieldDesc(_Fields setField) {" << endl; + indent(out) << "protected TField getFieldDesc(_Fields setField) {" << '\n'; indent_up(); const vector& members = tstruct->get_members(); vector::const_iterator m_iter; - indent(out) << "switch (setField) {" << endl; + indent(out) << "switch (setField) {" << '\n'; indent_up(); for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { t_field* field = (*m_iter); - indent(out) << "case " << constant_name(field->get_name()) << ":" << endl; - indent(out) << " return " << constant_name(field->get_name()) << "_FIELD_DESC;" << endl; + indent(out) << "case " << constant_name(field->get_name()) << ":" << '\n'; + indent(out) << " return " << constant_name(field->get_name()) << "_FIELD_DESC;" << '\n'; } - indent(out) << "default:" << endl; - indent(out) << " throw new IllegalArgumentException(\"Unknown field id \" + setField);" << endl; + indent(out) << "default:" << '\n'; + indent(out) << " throw new IllegalArgumentException(\"Unknown field id \" + setField);" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } void t_javame_generator::generate_get_struct_desc(ostream& out, t_struct* tstruct) { (void)tstruct; - indent(out) << "protected TStruct getStructDesc() {" << endl; - indent(out) << " return STRUCT_DESC;" << endl; - indent(out) << "}" << endl; + indent(out) << "protected TStruct getStructDesc() {" << '\n'; + indent(out) << " return STRUCT_DESC;" << '\n'; + indent(out) << "}" << '\n'; } void t_javame_generator::generate_union_comparisons(ostream& out, t_struct* tstruct) { // equality - indent(out) << "public boolean equals(Object other) {" << endl; - indent(out) << " if (other instanceof " << tstruct->get_name() << ") {" << endl; - indent(out) << " return equals((" << tstruct->get_name() << ")other);" << endl; - indent(out) << " } else {" << endl; - indent(out) << " return false;" << endl; - indent(out) << " }" << endl; - indent(out) << "}" << endl; + indent(out) << "public boolean equals(Object other) {" << '\n'; + indent(out) << " if (other instanceof " << tstruct->get_name() << ") {" << '\n'; + indent(out) << " return equals((" << tstruct->get_name() << ")other);" << '\n'; + indent(out) << " } else {" << '\n'; + indent(out) << " return false;" << '\n'; + indent(out) << " }" << '\n'; + indent(out) << "}" << '\n'; - out << endl; + out << '\n'; - indent(out) << "public boolean equals(" << tstruct->get_name() << " other) {" << endl; + indent(out) << "public boolean equals(" << tstruct->get_name() << " other) {" << '\n'; indent(out) << " return other != null && getSetField() == other.getSetField() && " - "getFieldValue().equals(other.getFieldValue());" << endl; - indent(out) << "}" << endl; - out << endl; + "getFieldValue().equals(other.getFieldValue());" << '\n'; + indent(out) << "}" << '\n'; + out << '\n'; - indent(out) << "public int compareTo(" << type_name(tstruct) << " other) {" << endl; + indent(out) << "public int compareTo(" << type_name(tstruct) << " other) {" << '\n'; indent(out) << " int lastComparison = TBaseHelper.compareTo(getSetField(), other.getSetField());" - << endl; - indent(out) << " if (lastComparison == 0) {" << endl; + << '\n'; + indent(out) << " if (lastComparison == 0) {" << '\n'; indent(out) << " return TBaseHelper.compareTo(getFieldValue(), other.getFieldValue());" - << endl; - indent(out) << " }" << endl; - indent(out) << " return lastComparison;" << endl; - indent(out) << "}" << endl; - out << endl; + << '\n'; + indent(out) << " }" << '\n'; + indent(out) << " return lastComparison;" << '\n'; + indent(out) << "}" << '\n'; + out << '\n'; } void t_javame_generator::generate_union_hashcode(ostream& out, t_struct* tstruct) { (void)tstruct; - indent(out) << "/**" << endl; + indent(out) << "/**" << '\n'; indent(out) << " * If you'd like this to perform more respectably, use the hashcode generator option." - << endl; - indent(out) << " */" << endl; - indent(out) << "public int hashCode() {" << endl; - indent(out) << " return 0;" << endl; - indent(out) << "}" << endl; + << '\n'; + indent(out) << " */" << '\n'; + indent(out) << "public int hashCode() {" << '\n'; + indent(out) << " return 0;" << '\n'; + indent(out) << "}" << '\n'; } /** @@ -1021,43 +1019,43 @@ void t_javame_generator::generate_java_struct_definition(ostream& out, const vector& members = tstruct->get_members(); vector::const_iterator m_iter; - out << endl; + out << '\n'; generate_field_descs(out, tstruct); - out << endl; + out << '\n'; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { indent(out) << "private "; - out << declare_field(*m_iter, false) << endl; + out << declare_field(*m_iter, false) << '\n'; } // isset data if (members.size() > 0) { - out << endl; + out << '\n'; - indent(out) << "// isset id assignments" << endl; + indent(out) << "// isset id assignments" << '\n'; int i = 0; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { if (!type_can_be_null((*m_iter)->get_type())) { indent(out) << "private static final int " << isset_field_id(*m_iter) << " = " << i << ";" - << endl; + << '\n'; i++; } } if (i > 0) { - indent(out) << "private boolean[] __isset_vector = new boolean[" << i << "];" << endl; + indent(out) << "private boolean[] __isset_vector = new boolean[" << i << "];" << '\n'; } - out << endl; + out << '\n'; } bool all_optional_members = true; // Default constructor - indent(out) << "public " << tstruct->get_name() << "() {" << endl; + indent(out) << "public " << tstruct->get_name() << "() {" << '\n'; indent_up(); for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { t_type* t = get_true_type((*m_iter)->get_type()); @@ -1074,49 +1072,49 @@ void t_javame_generator::generate_java_struct_definition(ostream& out, } } indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; if (!members.empty() && !all_optional_members) { // Full constructor for all fields - indent(out) << "public " << tstruct->get_name() << "(" << endl; + indent(out) << "public " << tstruct->get_name() << "(" << '\n'; indent_up(); bool first = true; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { if ((*m_iter)->get_req() != t_field::T_OPTIONAL) { if (!first) { - out << "," << endl; + out << "," << '\n'; } first = false; indent(out) << type_name((*m_iter)->get_type()) << " " << (*m_iter)->get_name(); } } - out << ")" << endl; + out << ")" << '\n'; indent_down(); - indent(out) << "{" << endl; + indent(out) << "{" << '\n'; indent_up(); - indent(out) << "this();" << endl; + indent(out) << "this();" << '\n'; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { if ((*m_iter)->get_req() != t_field::T_OPTIONAL) { indent(out) << "this." << (*m_iter)->get_name() << " = " << (*m_iter)->get_name() << ";" - << endl; + << '\n'; generate_isset_set(out, (*m_iter)); } } indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } // copy constructor - indent(out) << "/**" << endl; - indent(out) << " * Performs a deep copy on other." << endl; - indent(out) << " */" << endl; + indent(out) << "/**" << '\n'; + indent(out) << " * Performs a deep copy on other." << '\n'; + indent(out) << " */" << '\n'; indent(out) << "public " << tstruct->get_name() << "(" << tstruct->get_name() << " other) {" - << endl; + << '\n'; indent_up(); if (has_bit_vector(tstruct)) { indent(out) << "System.arraycopy(other.__isset_vector, 0, __isset_vector, 0, " - "other.__isset_vector.length);" << endl; + "other.__isset_vector.length);" << '\n'; } for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { @@ -1126,32 +1124,32 @@ void t_javame_generator::generate_java_struct_definition(ostream& out, bool can_be_null = type_can_be_null(type); if (can_be_null) { - indent(out) << "if (other." << generate_isset_check(field) << ") {" << endl; + indent(out) << "if (other." << generate_isset_check(field) << ") {" << '\n'; indent_up(); } if (type->is_container()) { generate_deep_copy_container(out, "other", field_name, "__this__" + field_name, type); - indent(out) << "this." << field_name << " = __this__" << field_name << ";" << endl; + indent(out) << "this." << field_name << " = __this__" << field_name << ";" << '\n'; } else { indent(out) << "this." << field_name << " = "; generate_deep_copy_non_container(out, "other." + field_name, field_name, type); - out << ";" << endl; + out << ";" << '\n'; } if (can_be_null) { indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } } indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; // clone method, so that you can deep copy an object when you don't know its class. - indent(out) << "public " << tstruct->get_name() << " deepCopy() {" << endl; - indent(out) << " return new " << tstruct->get_name() << "(this);" << endl; - indent(out) << "}" << endl << endl; + indent(out) << "public " << tstruct->get_name() << " deepCopy() {" << '\n'; + indent(out) << " return new " << tstruct->get_name() << "(this);" << '\n'; + indent(out) << "}" << '\n' << '\n'; generate_java_struct_clear(out, tstruct); @@ -1170,7 +1168,7 @@ void t_javame_generator::generate_java_struct_definition(ostream& out, generate_java_struct_tostring(out, tstruct); generate_java_validator(out, tstruct); scope_down(out); - out << endl; + out << '\n'; } /** @@ -1179,24 +1177,24 @@ void t_javame_generator::generate_java_struct_definition(ostream& out, * @param tstruct The struct definition */ void t_javame_generator::generate_java_struct_equality(ostream& out, t_struct* tstruct) { - out << indent() << "public boolean equals(Object that) {" << endl; + out << indent() << "public boolean equals(Object that) {" << '\n'; indent_up(); - out << indent() << "if (that == null)" << endl << indent() << " return false;" << endl - << indent() << "if (that instanceof " << tstruct->get_name() << ")" << endl << indent() - << " return this.equals((" << tstruct->get_name() << ")that);" << endl << indent() - << "return false;" << endl; + out << indent() << "if (that == null)" << '\n' << indent() << " return false;" << '\n' + << indent() << "if (that instanceof " << tstruct->get_name() << ")" << '\n' << indent() + << " return this.equals((" << tstruct->get_name() << ")that);" << '\n' << indent() + << "return false;" << '\n'; scope_down(out); - out << endl; + out << '\n'; - out << indent() << "public boolean equals(" << tstruct->get_name() << " that) {" << endl; + out << indent() << "public boolean equals(" << tstruct->get_name() << " that) {" << '\n'; indent_up(); - out << indent() << "if (that == null)" << endl << indent() << " return false;" << endl - << indent() << "if (this == that)" << endl << indent() << " return true;" << endl; + out << indent() << "if (that == null)" << '\n' << indent() << " return false;" << '\n' + << indent() << "if (this == that)" << '\n' << indent() << " return true;" << '\n'; const vector& members = tstruct->get_members(); vector::const_iterator m_iter; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { - out << endl; + out << '\n'; t_type* t = get_true_type((*m_iter)->get_type()); // Most existing Thrift code does not use isset or optional/required, @@ -1214,14 +1212,14 @@ void t_javame_generator::generate_java_struct_equality(ostream& out, t_struct* t that_present += " && that." + generate_isset_check(*m_iter); } - out << indent() << "boolean this_present_" << name << " = " << this_present << ";" << endl - << indent() << "boolean that_present_" << name << " = " << that_present << ";" << endl + out << indent() << "boolean this_present_" << name << " = " << this_present << ";" << '\n' + << indent() << "boolean that_present_" << name << " = " << that_present << ";" << '\n' << indent() << "if (" - << "this_present_" << name << " || that_present_" << name << ") {" << endl; + << "this_present_" << name << " || that_present_" << name << ") {" << '\n'; indent_up(); out << indent() << "if (!(" - << "this_present_" << name << " && that_present_" << name << "))" << endl << indent() - << " return false;" << endl; + << "this_present_" << name << " && that_present_" << name << "))" << '\n' << indent() + << " return false;" << '\n'; if (t->is_binary()) { unequal = "TBaseHelper.compareTo(this." + name + ", that." + name + ") != 0"; @@ -1231,66 +1229,66 @@ void t_javame_generator::generate_java_struct_equality(ostream& out, t_struct* t unequal = "this." + name + " != that." + name; } - out << indent() << "if (" << unequal << ")" << endl << indent() << " return false;" << endl; + out << indent() << "if (" << unequal << ")" << '\n' << indent() << " return false;" << '\n'; scope_down(out); } - out << endl; - indent(out) << "return true;" << endl; + out << '\n'; + indent(out) << "return true;" << '\n'; scope_down(out); - out << endl; + out << '\n'; - out << indent() << "public int hashCode() {" << endl; + out << indent() << "public int hashCode() {" << '\n'; indent_up(); - indent(out) << "return 0;" << endl; + indent(out) << "return 0;" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } void t_javame_generator::generate_java_struct_compare_to(ostream& out, t_struct* tstruct) { - indent(out) << "public int compareTo(Object otherObject) {" << endl; - // indent(out) << "public int compareTo(" << type_name(tstruct) << " other) {" << endl; + indent(out) << "public int compareTo(Object otherObject) {" << '\n'; + // indent(out) << "public int compareTo(" << type_name(tstruct) << " other) {" << '\n'; indent_up(); - indent(out) << "if (!getClass().equals(otherObject.getClass())) {" << endl; + indent(out) << "if (!getClass().equals(otherObject.getClass())) {" << '\n'; indent(out) << " return getClass().getName().compareTo(otherObject.getClass().getName());" - << endl; - indent(out) << "}" << endl; - out << endl; + << '\n'; + indent(out) << "}" << '\n'; + out << '\n'; indent(out) << type_name(tstruct) << " other = (" << type_name(tstruct) << ")otherObject;"; - indent(out) << "int lastComparison = 0;" << endl; - out << endl; + indent(out) << "int lastComparison = 0;" << '\n'; + out << '\n'; const vector& members = tstruct->get_members(); vector::const_iterator m_iter; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { t_field* field = *m_iter; indent(out) << "lastComparison = TBaseHelper.compareTo(" << generate_isset_check(field) - << ", other." << generate_isset_check(field) << ");" << endl; - indent(out) << "if (lastComparison != 0) {" << endl; - indent(out) << " return lastComparison;" << endl; - indent(out) << "}" << endl; + << ", other." << generate_isset_check(field) << ");" << '\n'; + indent(out) << "if (lastComparison != 0) {" << '\n'; + indent(out) << " return lastComparison;" << '\n'; + indent(out) << "}" << '\n'; - indent(out) << "if (" << generate_isset_check(field) << ") {" << endl; + indent(out) << "if (" << generate_isset_check(field) << ") {" << '\n'; if (field->get_type()->is_struct() || field->get_type()->is_xception()) { indent(out) << " lastComparison = this." << field->get_name() << ".compareTo(other." - << field->get_name() << ");" << endl; + << field->get_name() << ");" << '\n'; } else { indent(out) << " lastComparison = TBaseHelper.compareTo(this." << field->get_name() - << ", other." << field->get_name() << ");" << endl; + << ", other." << field->get_name() << ");" << '\n'; } - indent(out) << " if (lastComparison != 0) {" << endl; - indent(out) << " return lastComparison;" << endl; - indent(out) << " }" << endl; - indent(out) << "}" << endl; + indent(out) << " if (lastComparison != 0) {" << '\n'; + indent(out) << " return lastComparison;" << '\n'; + indent(out) << " }" << '\n'; + indent(out) << "}" << '\n'; } - indent(out) << "return 0;" << endl; + indent(out) << "return 0;" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } /** @@ -1299,91 +1297,91 @@ void t_javame_generator::generate_java_struct_compare_to(ostream& out, t_struct* * @param tstruct The struct definition */ void t_javame_generator::generate_java_struct_reader(ostream& out, t_struct* tstruct) { - out << indent() << "public void read(TProtocol iprot) throws TException {" << endl; + out << indent() << "public void read(TProtocol iprot) throws TException {" << '\n'; indent_up(); const vector& fields = tstruct->get_members(); vector::const_iterator f_iter; // Declare stack tmp variables and read struct header - out << indent() << "TField field;" << endl << indent() << "iprot.readStructBegin();" << endl; + out << indent() << "TField field;" << '\n' << indent() << "iprot.readStructBegin();" << '\n'; // Loop over reading in fields - indent(out) << "while (true)" << endl; + indent(out) << "while (true)" << '\n'; scope_up(out); // Read beginning field marker - indent(out) << "field = iprot.readFieldBegin();" << endl; + indent(out) << "field = iprot.readFieldBegin();" << '\n'; // Check for field STOP marker and break - indent(out) << "if (field.type == TType.STOP) { " << endl; + indent(out) << "if (field.type == TType.STOP) { " << '\n'; indent_up(); - indent(out) << "break;" << endl; + indent(out) << "break;" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; // Switch statement on the field we are reading - indent(out) << "switch (field.id) {" << endl; + indent(out) << "switch (field.id) {" << '\n'; indent_up(); // Generate deserialization code for known cases for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { indent(out) << "case " << (*f_iter)->get_key() << ": // " - << constant_name((*f_iter)->get_name()) << endl; + << constant_name((*f_iter)->get_name()) << '\n'; indent_up(); - indent(out) << "if (field.type == " << type_to_enum((*f_iter)->get_type()) << ") {" << endl; + indent(out) << "if (field.type == " << type_to_enum((*f_iter)->get_type()) << ") {" << '\n'; indent_up(); generate_deserialize_field(out, *f_iter, "this."); generate_isset_set(out, *f_iter); indent_down(); - out << indent() << "} else { " << endl << indent() << " TProtocolUtil.skip(iprot, field.type);" - << endl << indent() << "}" << endl << indent() << "break;" << endl; + out << indent() << "} else { " << '\n' << indent() << " TProtocolUtil.skip(iprot, field.type);" + << '\n' << indent() << "}" << '\n' << indent() << "break;" << '\n'; indent_down(); } - indent(out) << "default:" << endl; - indent(out) << " TProtocolUtil.skip(iprot, field.type);" << endl; + indent(out) << "default:" << '\n'; + indent(out) << " TProtocolUtil.skip(iprot, field.type);" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; // Read field end marker - indent(out) << "iprot.readFieldEnd();" << endl; + indent(out) << "iprot.readFieldEnd();" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; - out << indent() << "iprot.readStructEnd();" << endl; + out << indent() << "iprot.readStructEnd();" << '\n'; // performs various checks (e.g. check that all required fields are set) - indent(out) << "validate();" << endl; + indent(out) << "validate();" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } // generates java method to perform various checks // (e.g. check that all required fields are set) void t_javame_generator::generate_java_validator(ostream& out, t_struct* tstruct) { - indent(out) << "public void validate() throws TException {" << endl; + indent(out) << "public void validate() throws TException {" << '\n'; indent_up(); const vector& fields = tstruct->get_members(); vector::const_iterator f_iter; - out << indent() << "// check for required fields" << endl; + out << indent() << "// check for required fields" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if ((*f_iter)->get_req() == t_field::T_REQUIRED) { - out << indent() << "if (!" << generate_isset_check(*f_iter) << ") {" << endl << indent() + out << indent() << "if (!" << generate_isset_check(*f_iter) << ") {" << '\n' << indent() << " throw new TProtocolException(\"Required field '" << (*f_iter)->get_name() - << "' is unset! Struct:\" + toString());" << endl << indent() << "}" << endl << endl; + << "' is unset! Struct:\" + toString());" << '\n' << indent() << "}" << '\n' << '\n'; } } indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } /** @@ -1392,7 +1390,7 @@ void t_javame_generator::generate_java_validator(ostream& out, t_struct* tstruct * @param tstruct The struct definition */ void t_javame_generator::generate_java_struct_writer(ostream& out, t_struct* tstruct) { - out << indent() << "public void write(TProtocol oprot) throws TException {" << endl; + out << indent() << "public void write(TProtocol oprot) throws TException {" << '\n'; indent_up(); string name = tstruct->get_name(); @@ -1400,46 +1398,46 @@ void t_javame_generator::generate_java_struct_writer(ostream& out, t_struct* tst vector::const_iterator f_iter; // performs various checks (e.g. check that all required fields are set) - indent(out) << "validate();" << endl << endl; + indent(out) << "validate();" << '\n' << '\n'; - indent(out) << "oprot.writeStructBegin(STRUCT_DESC);" << endl; + indent(out) << "oprot.writeStructBegin(STRUCT_DESC);" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { bool null_allowed = type_can_be_null((*f_iter)->get_type()); if (null_allowed) { - out << indent() << "if (this." << (*f_iter)->get_name() << " != null) {" << endl; + out << indent() << "if (this." << (*f_iter)->get_name() << " != null) {" << '\n'; indent_up(); } bool optional = (*f_iter)->get_req() == t_field::T_OPTIONAL; if (optional) { - indent(out) << "if (" << generate_isset_check((*f_iter)) << ") {" << endl; + indent(out) << "if (" << generate_isset_check((*f_iter)) << ") {" << '\n'; indent_up(); } indent(out) << "oprot.writeFieldBegin(" << constant_name((*f_iter)->get_name()) - << "_FIELD_DESC);" << endl; + << "_FIELD_DESC);" << '\n'; // Write field contents generate_serialize_field(out, *f_iter, "this."); // Write field closer - indent(out) << "oprot.writeFieldEnd();" << endl; + indent(out) << "oprot.writeFieldEnd();" << '\n'; if (optional) { indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } if (null_allowed) { indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } } // Write the struct map - out << indent() << "oprot.writeFieldStop();" << endl << indent() << "oprot.writeStructEnd();" - << endl; + out << indent() << "oprot.writeFieldStop();" << '\n' << indent() << "oprot.writeStructEnd();" + << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } /** @@ -1451,62 +1449,62 @@ void t_javame_generator::generate_java_struct_writer(ostream& out, t_struct* tst * @param tstruct The struct definition */ void t_javame_generator::generate_java_struct_result_writer(ostream& out, t_struct* tstruct) { - out << indent() << "public void write(TProtocol oprot) throws TException {" << endl; + out << indent() << "public void write(TProtocol oprot) throws TException {" << '\n'; indent_up(); string name = tstruct->get_name(); const vector& fields = tstruct->get_sorted_members(); vector::const_iterator f_iter; - indent(out) << "oprot.writeStructBegin(STRUCT_DESC);" << endl; + indent(out) << "oprot.writeStructBegin(STRUCT_DESC);" << '\n'; bool first = true; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if (first) { first = false; - out << endl << indent() << "if "; + out << '\n' << indent() << "if "; } else { out << " else if "; } - out << "(this." << generate_isset_check(*f_iter) << ") {" << endl; + out << "(this." << generate_isset_check(*f_iter) << ") {" << '\n'; indent_up(); indent(out) << "oprot.writeFieldBegin(" << constant_name((*f_iter)->get_name()) - << "_FIELD_DESC);" << endl; + << "_FIELD_DESC);" << '\n'; // Write field contents generate_serialize_field(out, *f_iter, "this."); // Write field closer - indent(out) << "oprot.writeFieldEnd();" << endl; + indent(out) << "oprot.writeFieldEnd();" << '\n'; indent_down(); indent(out) << "}"; } // Write the struct map - out << endl << indent() << "oprot.writeFieldStop();" << endl << indent() - << "oprot.writeStructEnd();" << endl; + out << '\n' << indent() << "oprot.writeFieldStop();" << '\n' << indent() + << "oprot.writeStructEnd();" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } void t_javame_generator::generate_reflection_getters(ostringstream& out, t_type* type, string field_name, string cap_name) { - indent(out) << "case " << constant_name(field_name) << ":" << endl; + indent(out) << "case " << constant_name(field_name) << ":" << '\n'; indent_up(); if (type->is_base_type() && !type->is_string()) { t_base_type* base_type = (t_base_type*)type; indent(out) << "return new " << type_name(type, true, false) << "(" - << (base_type->is_bool() ? "is" : "get") << cap_name << "());" << endl << endl; + << (base_type->is_bool() ? "is" : "get") << cap_name << "());" << '\n' << '\n'; } else { - indent(out) << "return get" << cap_name << "();" << endl << endl; + indent(out) << "return get" << cap_name << "();" << '\n' << '\n'; } indent_down(); @@ -1516,14 +1514,14 @@ void t_javame_generator::generate_reflection_setters(ostringstream& out, t_type* type, string field_name, string cap_name) { - indent(out) << "case " << constant_name(field_name) << ":" << endl; + indent(out) << "case " << constant_name(field_name) << ":" << '\n'; indent_up(); - indent(out) << "if (value == null) {" << endl; - indent(out) << " unset" << get_cap_name(field_name) << "();" << endl; - indent(out) << "} else {" << endl; - indent(out) << " set" << cap_name << "((" << type_name(type, true, false) << ")value);" << endl; - indent(out) << "}" << endl; - indent(out) << "break;" << endl << endl; + indent(out) << "if (value == null) {" << '\n'; + indent(out) << " unset" << get_cap_name(field_name) << "();" << '\n'; + indent(out) << "} else {" << '\n'; + indent(out) << " set" << cap_name << "((" << type_name(type, true, false) << ")value);" << '\n'; + indent(out) << "}" << '\n'; + indent(out) << "break;" << '\n' << '\n'; indent_down(); } @@ -1568,13 +1566,13 @@ void t_javame_generator::generate_java_bean_boilerplate(ostream& out, t_struct* if (type->is_container()) { // Method to return the size of the collection indent(out) << "public int get" << cap_name; - out << get_cap_name("size() {") << endl; + out << get_cap_name("size() {") << '\n'; indent_up(); indent(out) << "return (this." << field_name << " == null) ? 0 : " - << "this." << field_name << ".size();" << endl; + << "this." << field_name << ".size();" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } if (type->is_set() || type->is_list()) { @@ -1588,35 +1586,35 @@ void t_javame_generator::generate_java_bean_boilerplate(ostream& out, t_struct* // Iterator getter for sets and lists indent(out) << "public Enumeration get" << cap_name; - out << get_cap_name("Enumeration() {") << endl; + out << get_cap_name("Enumeration() {") << '\n'; indent_up(); indent(out) << "return (this." << field_name << " == null) ? null : " - << "this." << field_name << ".elements();" << endl; + << "this." << field_name << ".elements();" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; // Add to set or list, create if the set/list is null indent(out); out << "public void add" << get_cap_name("to"); - out << cap_name << "(" << type_name(element_type) << " elem) {" << endl; + out << cap_name << "(" << type_name(element_type) << " elem) {" << '\n'; indent_up(); - indent(out) << "if (this." << field_name << " == null) {" << endl; + indent(out) << "if (this." << field_name << " == null) {" << '\n'; indent_up(); indent(out) << "this." << field_name << " = new " << type_name(type, false, true) << "();" - << endl; + << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; if (type->is_set()) { indent(out) << "this." << field_name << ".put(" << box_type(element_type, "elem") << ", " - << box_type(element_type, "elem") << ");" << endl; + << box_type(element_type, "elem") << ");" << '\n'; } else { indent(out) << "this." << field_name << ".addElement(" << box_type(element_type, "elem") - << ");" << endl; + << ");" << '\n'; } indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } else if (type->is_map()) { // Put to map @@ -1625,18 +1623,18 @@ void t_javame_generator::generate_java_bean_boilerplate(ostream& out, t_struct* indent(out); out << "public void putTo" << cap_name << "(" << type_name(key_type, true) << " key, " - << type_name(val_type, true) << " val) {" << endl; + << type_name(val_type, true) << " val) {" << '\n'; indent_up(); - indent(out) << "if (this." << field_name << " == null) {" << endl; + indent(out) << "if (this." << field_name << " == null) {" << '\n'; indent_up(); indent(out) << "this." << field_name << " = new " << type_name(type, false, true) << "();" - << endl; + << '\n'; indent_down(); - indent(out) << "}" << endl; - indent(out) << "this." << field_name << ".put(key, val);" << endl; + indent(out) << "}" << '\n'; + indent(out) << "this." << field_name << ".put(key, val);" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } // Simple getter @@ -1647,60 +1645,60 @@ void t_javame_generator::generate_java_bean_boilerplate(ostream& out, t_struct* } else { out << " get"; } - out << cap_name << "() {" << endl; + out << cap_name << "() {" << '\n'; indent_up(); - indent(out) << "return this." << field_name << ";" << endl; + indent(out) << "return this." << field_name << ";" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; // Simple setter generate_java_doc(out, field); indent(out) << "public "; out << "void"; - out << " set" << cap_name << "(" << type_name(type) << " " << field_name << ") {" << endl; + out << " set" << cap_name << "(" << type_name(type) << " " << field_name << ") {" << '\n'; indent_up(); - indent(out) << "this." << field_name << " = " << field_name << ";" << endl; + indent(out) << "this." << field_name << " = " << field_name << ";" << '\n'; generate_isset_set(out, field); indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; // Unsetter - indent(out) << "public void unset" << cap_name << "() {" << endl; + indent(out) << "public void unset" << cap_name << "() {" << '\n'; indent_up(); if (type_can_be_null(type)) { - indent(out) << "this." << field_name << " = null;" << endl; + indent(out) << "this." << field_name << " = null;" << '\n'; } else { - indent(out) << "__isset_vector[" << isset_field_id(field) << "] = false;" << endl; + indent(out) << "__isset_vector[" << isset_field_id(field) << "] = false;" << '\n'; } indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; // isSet method indent(out) << "/** Returns true if field " << field_name - << " is set (has been assigned a value) and false otherwise */" << endl; - indent(out) << "public boolean is" << get_cap_name("set") << cap_name << "() {" << endl; + << " is set (has been assigned a value) and false otherwise */" << '\n'; + indent(out) << "public boolean is" << get_cap_name("set") << cap_name << "() {" << '\n'; indent_up(); if (type_can_be_null(type)) { - indent(out) << "return this." << field_name << " != null;" << endl; + indent(out) << "return this." << field_name << " != null;" << '\n'; } else { - indent(out) << "return __isset_vector[" << isset_field_id(field) << "];" << endl; + indent(out) << "return __isset_vector[" << isset_field_id(field) << "];" << '\n'; } indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; indent(out) << "public void set" << cap_name << get_cap_name("isSet") << "(boolean value) {" - << endl; + << '\n'; indent_up(); if (type_can_be_null(type)) { - indent(out) << "if (!value) {" << endl; - indent(out) << " this." << field_name << " = null;" << endl; - indent(out) << "}" << endl; + indent(out) << "if (!value) {" << '\n'; + indent(out) << " this." << field_name << " = null;" << '\n'; + indent(out) << "}" << '\n'; } else { - indent(out) << "__isset_vector[" << isset_field_id(field) << "] = value;" << endl; + indent(out) << "__isset_vector[" << isset_field_id(field) << "] = value;" << '\n'; } indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } } @@ -1710,12 +1708,12 @@ void t_javame_generator::generate_java_bean_boilerplate(ostream& out, t_struct* * @param tstruct The struct definition */ void t_javame_generator::generate_java_struct_tostring(ostream& out, t_struct* tstruct) { - out << indent() << "public String toString() {" << endl; + out << indent() << "public String toString() {" << '\n'; indent_up(); out << indent() << "StringBuffer sb = new StringBuffer(\"" << tstruct->get_name() << "(\");" - << endl; - out << indent() << "boolean first = true;" << endl << endl; + << '\n'; + out << indent() << "boolean first = true;" << '\n' << '\n'; const vector& fields = tstruct->get_members(); vector::const_iterator f_iter; @@ -1723,46 +1721,46 @@ void t_javame_generator::generate_java_struct_tostring(ostream& out, t_struct* t for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { bool could_be_unset = (*f_iter)->get_req() == t_field::T_OPTIONAL; if (could_be_unset) { - indent(out) << "if (" << generate_isset_check(*f_iter) << ") {" << endl; + indent(out) << "if (" << generate_isset_check(*f_iter) << ") {" << '\n'; indent_up(); } t_field* field = (*f_iter); if (!first) { - indent(out) << "if (!first) sb.append(\", \");" << endl; + indent(out) << "if (!first) sb.append(\", \");" << '\n'; } - indent(out) << "sb.append(\"" << (*f_iter)->get_name() << ":\");" << endl; + indent(out) << "sb.append(\"" << (*f_iter)->get_name() << ":\");" << '\n'; bool can_be_null = type_can_be_null(field->get_type()); if (can_be_null) { - indent(out) << "if (this." << (*f_iter)->get_name() << " == null) {" << endl; - indent(out) << " sb.append(\"null\");" << endl; - indent(out) << "} else {" << endl; + indent(out) << "if (this." << (*f_iter)->get_name() << " == null) {" << '\n'; + indent(out) << " sb.append(\"null\");" << '\n'; + indent(out) << "} else {" << '\n'; indent_up(); } if (field->get_type()->is_binary()) { - indent(out) << "TBaseHelper.toString(this." << field->get_name() << ", sb);" << endl; + indent(out) << "TBaseHelper.toString(this." << field->get_name() << ", sb);" << '\n'; } else { - indent(out) << "sb.append(this." << (*f_iter)->get_name() << ");" << endl; + indent(out) << "sb.append(this." << (*f_iter)->get_name() << ");" << '\n'; } if (can_be_null) { indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } - indent(out) << "first = false;" << endl; + indent(out) << "first = false;" << '\n'; if (could_be_unset) { indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } first = false; } - out << indent() << "sb.append(\")\");" << endl << indent() << "return sb.toString();" << endl; + out << indent() << "sb.append(\")\");" << '\n' << indent() << "return sb.toString();" << '\n'; indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } /** @@ -1821,7 +1819,7 @@ std::string t_javame_generator::get_java_type_string(t_type* type) { } void t_javame_generator::generate_field_value_meta_data(std::ostream& out, t_type* type) { - out << endl; + out << '\n'; indent_up(); indent_up(); if (type->is_struct() || type->is_xception()) { @@ -1871,7 +1869,7 @@ void t_javame_generator::generate_service(t_service* tservice) { f_service_ << autogen_comment() << java_package() << java_type_imports() << java_thrift_imports(); - f_service_ << "public class " << service_name_ << " {" << endl << endl; + f_service_ << "public class " << service_name_ << " {" << '\n' << '\n'; indent_up(); // Generate the three main parts of the service @@ -1881,7 +1879,7 @@ void t_javame_generator::generate_service(t_service* tservice) { generate_service_helpers(tservice); indent_down(); - f_service_ << "}" << endl; + f_service_ << "}" << '\n'; f_service_.close(); } @@ -1892,7 +1890,7 @@ void t_javame_generator::generate_service(t_service* tservice) { */ void t_javame_generator::generate_primitive_service_interface(t_service* tservice) { f_service_ << indent() << "public interface Iface extends " << service_name_ << "Iface { }" - << endl << endl; + << '\n' << '\n'; string f_interface_name = package_dir_ + "/" + service_name_ + "Iface.java"; ofstream_with_content_based_conditional_update f_iface; @@ -1905,15 +1903,15 @@ void t_javame_generator::generate_primitive_service_interface(t_service* tservic f_iface << autogen_comment() << java_package() << java_type_imports() << java_thrift_imports(); generate_java_doc(f_iface, tservice); - f_iface << "public interface " << service_name_ << "Iface" << extends_iface << " {" << endl - << endl; + f_iface << "public interface " << service_name_ << "Iface" << extends_iface << " {" << '\n' + << '\n'; vector functions = tservice->get_functions(); vector::iterator f_iter; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { generate_java_doc(f_iface, *f_iter); - f_iface << " public " << function_signature(*f_iter) << ";" << endl << endl; + f_iface << " public " << function_signature(*f_iter) << ";" << '\n' << '\n'; } - f_iface << "}" << endl << endl; + f_iface << "}" << '\n' << '\n'; } /** @@ -1930,16 +1928,16 @@ void t_javame_generator::generate_service_interface(t_service* tservice) { } generate_java_doc(f_service_, tservice); - f_service_ << indent() << "public interface Iface" << extends_iface << " {" << endl << endl; + f_service_ << indent() << "public interface Iface" << extends_iface << " {" << '\n' << '\n'; indent_up(); vector functions = tservice->get_functions(); vector::iterator f_iter; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { generate_java_doc(f_service_, *f_iter); - indent(f_service_) << "public " << function_signature(*f_iter) << ";" << endl << endl; + indent(f_service_) << "public " << function_signature(*f_iter) << ";" << '\n' << '\n'; } indent_down(); - f_service_ << indent() << "}" << endl << endl; + f_service_ << indent() << "}" << '\n' << '\n'; } /** @@ -1971,41 +1969,41 @@ void t_javame_generator::generate_service_client(t_service* tservice) { } indent(f_service_) << "public static class Client" << extends_client - << " implements TServiceClient, Iface {" << endl; + << " implements TServiceClient, Iface {" << '\n'; indent_up(); - indent(f_service_) << "public Client(TProtocol prot)" << endl; + indent(f_service_) << "public Client(TProtocol prot)" << '\n'; scope_up(f_service_); - indent(f_service_) << "this(prot, prot);" << endl; + indent(f_service_) << "this(prot, prot);" << '\n'; scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; - indent(f_service_) << "public Client(TProtocol iprot, TProtocol oprot)" << endl; + indent(f_service_) << "public Client(TProtocol iprot, TProtocol oprot)" << '\n'; scope_up(f_service_); if (extends.empty()) { - f_service_ << indent() << "iprot_ = iprot;" << endl << indent() << "oprot_ = oprot;" << endl; + f_service_ << indent() << "iprot_ = iprot;" << '\n' << indent() << "oprot_ = oprot;" << '\n'; } else { - f_service_ << indent() << "super(iprot, oprot);" << endl; + f_service_ << indent() << "super(iprot, oprot);" << '\n'; } scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; if (extends.empty()) { - f_service_ << indent() << "protected TProtocol iprot_;" << endl << indent() - << "protected TProtocol oprot_;" << endl << endl << indent() - << "protected int seqid_;" << endl << endl; + f_service_ << indent() << "protected TProtocol iprot_;" << '\n' << indent() + << "protected TProtocol oprot_;" << '\n' << '\n' << indent() + << "protected int seqid_;" << '\n' << '\n'; - indent(f_service_) << "public TProtocol getInputProtocol()" << endl; + indent(f_service_) << "public TProtocol getInputProtocol()" << '\n'; scope_up(f_service_); - indent(f_service_) << "return this.iprot_;" << endl; + indent(f_service_) << "return this.iprot_;" << '\n'; scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; - indent(f_service_) << "public TProtocol getOutputProtocol()" << endl; + indent(f_service_) << "public TProtocol getOutputProtocol()" << '\n'; scope_up(f_service_); - indent(f_service_) << "return this.oprot_;" << endl; + indent(f_service_) << "return this.oprot_;" << '\n'; scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; } // Generate client method implementations @@ -2015,7 +2013,7 @@ void t_javame_generator::generate_service_client(t_service* tservice) { string funname = (*f_iter)->get_name(); // Open function - indent(f_service_) << "public " << function_signature(*f_iter) << endl; + indent(f_service_) << "public " << function_signature(*f_iter) << '\n'; scope_up(f_service_); indent(f_service_) << "send_" << funname << "("; @@ -2034,17 +2032,17 @@ void t_javame_generator::generate_service_client(t_service* tservice) { } f_service_ << (*fld_iter)->get_name(); } - f_service_ << ");" << endl; + f_service_ << ");" << '\n'; if (!(*f_iter)->is_oneway()) { f_service_ << indent(); if (!(*f_iter)->get_returntype()->is_void()) { f_service_ << "return "; } - f_service_ << "recv_" << funname << "();" << endl; + f_service_ << "recv_" << funname << "();" << '\n'; } scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; t_function send_function(g_type_void, string("send_") + (*f_iter)->get_name(), @@ -2053,26 +2051,26 @@ void t_javame_generator::generate_service_client(t_service* tservice) { string argsname = (*f_iter)->get_name() + "_args"; // Open function - indent(f_service_) << "public " << function_signature(&send_function) << endl; + indent(f_service_) << "public " << function_signature(&send_function) << '\n'; scope_up(f_service_); // Serialize the request f_service_ << indent() << "oprot_.writeMessageBegin(new TMessage(\"" << funname << "\", " << ((*f_iter)->is_oneway() ? "TMessageType.ONEWAY" : "TMessageType.CALL") - << ", ++seqid_));" << endl << indent() << argsname << " args = new " << argsname - << "();" << endl; + << ", ++seqid_));" << '\n' << indent() << argsname << " args = new " << argsname + << "();" << '\n'; for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) { f_service_ << indent() << "args.set" << get_cap_name((*fld_iter)->get_name()) << "(" - << (*fld_iter)->get_name() << ");" << endl; + << (*fld_iter)->get_name() << ");" << '\n'; } - f_service_ << indent() << "args.write(oprot_);" << endl << indent() - << "oprot_.writeMessageEnd();" << endl << indent() - << "oprot_.getTransport().flush();" << endl; + f_service_ << indent() << "args.write(oprot_);" << '\n' << indent() + << "oprot_.writeMessageEnd();" << '\n' << indent() + << "oprot_.getTransport().flush();" << '\n'; scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; if (!(*f_iter)->is_oneway()) { string resultname = (*f_iter)->get_name() + "_result"; @@ -2083,53 +2081,53 @@ void t_javame_generator::generate_service_client(t_service* tservice) { &noargs, (*f_iter)->get_xceptions()); // Open function - indent(f_service_) << "public " << function_signature(&recv_function) << endl; + indent(f_service_) << "public " << function_signature(&recv_function) << '\n'; scope_up(f_service_); - f_service_ << indent() << "TMessage msg = iprot_.readMessageBegin();" << endl << indent() - << "if (msg.type == TMessageType.EXCEPTION) {" << endl << indent() - << " TApplicationException x = TApplicationException.read(iprot_);" << endl - << indent() << " iprot_.readMessageEnd();" << endl << indent() << " throw x;" - << endl << indent() << "}" << endl << indent() << "if (msg.seqid != seqid_) {" - << endl << indent() + f_service_ << indent() << "TMessage msg = iprot_.readMessageBegin();" << '\n' << indent() + << "if (msg.type == TMessageType.EXCEPTION) {" << '\n' << indent() + << " TApplicationException x = TApplicationException.read(iprot_);" << '\n' + << indent() << " iprot_.readMessageEnd();" << '\n' << indent() << " throw x;" + << '\n' << indent() << "}" << '\n' << indent() << "if (msg.seqid != seqid_) {" + << '\n' << indent() << " throw new TApplicationException(TApplicationException.BAD_SEQUENCE_ID, \"" - << (*f_iter)->get_name() << " failed: out of sequence response\");" << endl - << indent() << "}" << endl << indent() << resultname << " result = new " - << resultname << "();" << endl << indent() << "result.read(iprot_);" << endl - << indent() << "iprot_.readMessageEnd();" << endl; + << (*f_iter)->get_name() << " failed: out of sequence response\");" << '\n' + << indent() << "}" << '\n' << indent() << resultname << " result = new " + << resultname << "();" << '\n' << indent() << "result.read(iprot_);" << '\n' + << indent() << "iprot_.readMessageEnd();" << '\n'; // Careful, only return _result if not a void function if (!(*f_iter)->get_returntype()->is_void()) { - f_service_ << indent() << "if (result." << generate_isset_check("success") << ") {" << endl - << indent() << " return result.success;" << endl << indent() << "}" << endl; + f_service_ << indent() << "if (result." << generate_isset_check("success") << ") {" << '\n' + << indent() << " return result.success;" << '\n' << indent() << "}" << '\n'; } t_struct* xs = (*f_iter)->get_xceptions(); const std::vector& xceptions = xs->get_members(); vector::const_iterator x_iter; for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { - f_service_ << indent() << "if (result." << (*x_iter)->get_name() << " != null) {" << endl - << indent() << " throw result." << (*x_iter)->get_name() << ";" << endl - << indent() << "}" << endl; + f_service_ << indent() << "if (result." << (*x_iter)->get_name() << " != null) {" << '\n' + << indent() << " throw result." << (*x_iter)->get_name() << ";" << '\n' + << indent() << "}" << '\n'; } // If you get here it's an exception, unless a void function if ((*f_iter)->get_returntype()->is_void()) { - indent(f_service_) << "return;" << endl; + indent(f_service_) << "return;" << '\n'; } else { f_service_ << indent() << "throw new TApplicationException(TApplicationException.MISSING_RESULT, \"" - << (*f_iter)->get_name() << " failed: unknown result\");" << endl; + << (*f_iter)->get_name() << " failed: unknown result\");" << '\n'; } // Close function scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; } } indent_down(); - indent(f_service_) << "}" << endl; + indent(f_service_) << "}" << '\n'; } /** @@ -2152,66 +2150,66 @@ void t_javame_generator::generate_service_server(t_service* tservice) { // Generate the header portion indent(f_service_) << "public static class Processor" << extends_processor - << " implements TProcessor {" << endl; + << " implements TProcessor {" << '\n'; indent_up(); - indent(f_service_) << "public Processor(Iface iface)" << endl; + indent(f_service_) << "public Processor(Iface iface)" << '\n'; scope_up(f_service_); if (!extends.empty()) { - f_service_ << indent() << "super(iface);" << endl; + f_service_ << indent() << "super(iface);" << '\n'; } - f_service_ << indent() << "iface_ = iface;" << endl; + f_service_ << indent() << "iface_ = iface;" << '\n'; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { f_service_ << indent() << "processMap_.put(\"" << (*f_iter)->get_name() << "\", new " - << (*f_iter)->get_name() << "());" << endl; + << (*f_iter)->get_name() << "());" << '\n'; } scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; if (extends.empty()) { f_service_ - << indent() << "protected static interface ProcessFunction {" << endl << indent() + << indent() << "protected static interface ProcessFunction {" << '\n' << indent() << " public void process(int seqid, TProtocol iprot, TProtocol oprot) throws TException;" - << endl << indent() << "}" << endl << endl; + << '\n' << indent() << "}" << '\n' << '\n'; } - f_service_ << indent() << "private Iface iface_;" << endl; + f_service_ << indent() << "private Iface iface_;" << '\n'; if (extends.empty()) { - f_service_ << indent() << "protected final Hashtable processMap_ = new Hashtable();" << endl; + f_service_ << indent() << "protected final Hashtable processMap_ = new Hashtable();" << '\n'; } - f_service_ << endl; + f_service_ << '\n'; // Generate the server implementation indent(f_service_) << "public boolean process(TProtocol iprot, TProtocol oprot) throws TException" - << endl; + << '\n'; scope_up(f_service_); - f_service_ << indent() << "TMessage msg = iprot.readMessageBegin();" << endl; + f_service_ << indent() << "TMessage msg = iprot.readMessageBegin();" << '\n'; // TODO(mcslee): validate message, was the seqid etc. legit? f_service_ - << indent() << "ProcessFunction fn = (ProcessFunction)processMap_.get(msg.name);" << endl - << indent() << "if (fn == null) {" << endl << indent() - << " TProtocolUtil.skip(iprot, TType.STRUCT);" << endl << indent() - << " iprot.readMessageEnd();" << endl << indent() + << indent() << "ProcessFunction fn = (ProcessFunction)processMap_.get(msg.name);" << '\n' + << indent() << "if (fn == null) {" << '\n' << indent() + << " TProtocolUtil.skip(iprot, TType.STRUCT);" << '\n' << indent() + << " iprot.readMessageEnd();" << '\n' << indent() << " TApplicationException x = new " "TApplicationException(TApplicationException.UNKNOWN_METHOD, \"Invalid method name: " - "'\"+msg.name+\"'\");" << endl << indent() + "'\"+msg.name+\"'\");" << '\n' << indent() << " oprot.writeMessageBegin(new TMessage(msg.name, TMessageType.EXCEPTION, msg.seqid));" - << endl << indent() << " x.write(oprot);" << endl << indent() << " oprot.writeMessageEnd();" - << endl << indent() << " oprot.getTransport().flush();" << endl << indent() - << " return true;" << endl << indent() << "}" << endl << indent() - << "fn.process(msg.seqid, iprot, oprot);" << endl; + << '\n' << indent() << " x.write(oprot);" << '\n' << indent() << " oprot.writeMessageEnd();" + << '\n' << indent() << " oprot.getTransport().flush();" << '\n' << indent() + << " return true;" << '\n' << indent() << "}" << '\n' << indent() + << "fn.process(msg.seqid, iprot, oprot);" << '\n'; - f_service_ << indent() << "return true;" << endl; + f_service_ << indent() << "return true;" << '\n'; scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; // Generate the process subfunctions for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { @@ -2219,7 +2217,7 @@ void t_javame_generator::generate_service_server(t_service* tservice) { } indent_down(); - indent(f_service_) << "}" << endl << endl; + indent(f_service_) << "}" << '\n' << '\n'; } /** @@ -2257,36 +2255,36 @@ void t_javame_generator::generate_process_function(t_service* tservice, t_functi (void)tservice; // Open class indent(f_service_) << "private class " << tfunction->get_name() << " implements ProcessFunction {" - << endl; + << '\n'; indent_up(); // Open function indent(f_service_) << "public void process(int seqid, TProtocol iprot, TProtocol oprot) throws TException" - << endl; + << '\n'; scope_up(f_service_); string argsname = tfunction->get_name() + "_args"; string resultname = tfunction->get_name() + "_result"; - f_service_ << indent() << argsname << " args = new " << argsname << "();" << endl << indent() - << "try {" << endl; + f_service_ << indent() << argsname << " args = new " << argsname << "();" << '\n' << indent() + << "try {" << '\n'; indent_up(); - f_service_ << indent() << "args.read(iprot);" << endl; + f_service_ << indent() << "args.read(iprot);" << '\n'; indent_down(); - f_service_ << indent() << "} catch (TProtocolException e) {" << endl; + f_service_ << indent() << "} catch (TProtocolException e) {" << '\n'; indent_up(); - f_service_ << indent() << "iprot.readMessageEnd();" << endl << indent() + f_service_ << indent() << "iprot.readMessageEnd();" << '\n' << indent() << "TApplicationException x = new " "TApplicationException(TApplicationException.PROTOCOL_ERROR, e.getMessage());" - << endl << indent() << "oprot.writeMessageBegin(new TMessage(\"" - << tfunction->get_name() << "\", TMessageType.EXCEPTION, seqid));" << endl << indent() - << "x.write(oprot);" << endl << indent() << "oprot.writeMessageEnd();" << endl - << indent() << "oprot.getTransport().flush();" << endl << indent() << "return;" - << endl; + << '\n' << indent() << "oprot.writeMessageBegin(new TMessage(\"" + << tfunction->get_name() << "\", TMessageType.EXCEPTION, seqid));" << '\n' << indent() + << "x.write(oprot);" << '\n' << indent() << "oprot.writeMessageEnd();" << '\n' + << indent() << "oprot.getTransport().flush();" << '\n' << indent() << "return;" + << '\n'; indent_down(); - f_service_ << indent() << "}" << endl; - f_service_ << indent() << "iprot.readMessageEnd();" << endl; + f_service_ << indent() << "}" << '\n'; + f_service_ << indent() << "iprot.readMessageEnd();" << '\n'; t_struct* xs = tfunction->get_xceptions(); const std::vector& xceptions = xs->get_members(); @@ -2294,12 +2292,12 @@ void t_javame_generator::generate_process_function(t_service* tservice, t_functi // Declare result for non oneway function if (!tfunction->is_oneway()) { - f_service_ << indent() << resultname << " result = new " << resultname << "();" << endl; + f_service_ << indent() << resultname << " result = new " << resultname << "();" << '\n'; } // Try block for a function with exceptions if (xceptions.size() > 0) { - f_service_ << indent() << "try {" << endl; + f_service_ << indent() << "try {" << '\n'; indent_up(); } @@ -2322,13 +2320,13 @@ void t_javame_generator::generate_process_function(t_service* tservice, t_functi } f_service_ << "args." << (*f_iter)->get_name(); } - f_service_ << ");" << endl; + f_service_ << ");" << '\n'; // Set isset on success field if (!tfunction->is_oneway() && !tfunction->get_returntype()->is_void() && !type_can_be_null(tfunction->get_returntype())) { f_service_ << indent() << "result.set" << get_cap_name("success") << get_cap_name("isSet") - << "(true);" << endl; + << "(true);" << '\n'; } if (!tfunction->is_oneway() && xceptions.size() > 0) { @@ -2336,54 +2334,54 @@ void t_javame_generator::generate_process_function(t_service* tservice, t_functi f_service_ << indent() << "}"; for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { f_service_ << " catch (" << type_name((*x_iter)->get_type(), false, false) << " " - << (*x_iter)->get_name() << ") {" << endl; + << (*x_iter)->get_name() << ") {" << '\n'; if (!tfunction->is_oneway()) { indent_up(); f_service_ << indent() << "result." << (*x_iter)->get_name() << " = " - << (*x_iter)->get_name() << ";" << endl; + << (*x_iter)->get_name() << ";" << '\n'; indent_down(); f_service_ << indent() << "}"; } else { f_service_ << "}"; } } - f_service_ << " catch (Throwable th) {" << endl; + f_service_ << " catch (Throwable th) {" << '\n'; indent_up(); f_service_ << indent() << "TApplicationException x = new " "TApplicationException(TApplicationException.INTERNAL_ERROR, " "\"Internal error processing " << tfunction->get_name() << "\");" - << endl << indent() << "oprot.writeMessageBegin(new TMessage(\"" - << tfunction->get_name() << "\", TMessageType.EXCEPTION, seqid));" << endl - << indent() << "x.write(oprot);" << endl << indent() << "oprot.writeMessageEnd();" - << endl << indent() << "oprot.getTransport().flush();" << endl << indent() - << "return;" << endl; + << '\n' << indent() << "oprot.writeMessageBegin(new TMessage(\"" + << tfunction->get_name() << "\", TMessageType.EXCEPTION, seqid));" << '\n' + << indent() << "x.write(oprot);" << '\n' << indent() << "oprot.writeMessageEnd();" + << '\n' << indent() << "oprot.getTransport().flush();" << '\n' << indent() + << "return;" << '\n'; indent_down(); - f_service_ << indent() << "}" << endl; + f_service_ << indent() << "}" << '\n'; } // Shortcut out here for oneway functions if (tfunction->is_oneway()) { - f_service_ << indent() << "return;" << endl; + f_service_ << indent() << "return;" << '\n'; scope_down(f_service_); // Close class indent_down(); - f_service_ << indent() << "}" << endl << endl; + f_service_ << indent() << "}" << '\n' << '\n'; return; } f_service_ << indent() << "oprot.writeMessageBegin(new TMessage(\"" << tfunction->get_name() - << "\", TMessageType.REPLY, seqid));" << endl << indent() << "result.write(oprot);" - << endl << indent() << "oprot.writeMessageEnd();" << endl << indent() - << "oprot.getTransport().flush();" << endl; + << "\", TMessageType.REPLY, seqid));" << '\n' << indent() << "result.write(oprot);" + << '\n' << indent() << "oprot.writeMessageEnd();" << '\n' << indent() + << "oprot.getTransport().flush();" << '\n'; // Close function scope_down(f_service_); - f_service_ << endl; + f_service_ << '\n'; // Close class indent_down(); - f_service_ << indent() << "}" << endl << endl; + f_service_ << indent() << "}" << '\n' << '\n'; } /** @@ -2441,11 +2439,11 @@ void t_javame_generator::generate_deserialize_field(ostream& out, t_field* tfiel default: throw "compiler error: no Java name for base type " + t_base_type::t_base_name(tbase); } - out << endl; + out << '\n'; } else if (type->is_enum()) { indent(out) << name << " = " << type_name(tfield->get_type(), true, false) + ".findByValue(iprot.readI32());" - << endl; + << '\n'; } else { printf("DO NOT KNOW HOW TO DESERIALIZE FIELD '%s' TYPE '%s'\n", tfield->get_name().c_str(), @@ -2459,8 +2457,8 @@ void t_javame_generator::generate_deserialize_field(ostream& out, t_field* tfiel void t_javame_generator::generate_deserialize_struct(ostream& out, t_struct* tstruct, string prefix) { - out << indent() << prefix << " = new " << type_name(tstruct) << "();" << endl << indent() - << prefix << ".read(iprot);" << endl; + out << indent() << prefix << " = new " << type_name(tstruct) << "();" << '\n' << indent() + << prefix << ".read(iprot);" << '\n'; } /** @@ -2483,23 +2481,23 @@ void t_javame_generator::generate_deserialize_container(ostream& out, // Declare variables, read header if (ttype->is_map()) { - indent(out) << "TMap " << obj << " = iprot.readMapBegin();" << endl; + indent(out) << "TMap " << obj << " = iprot.readMapBegin();" << '\n'; } else if (ttype->is_set()) { - indent(out) << "TSet " << obj << " = iprot.readSetBegin();" << endl; + indent(out) << "TSet " << obj << " = iprot.readSetBegin();" << '\n'; } else if (ttype->is_list()) { - indent(out) << "TList " << obj << " = iprot.readListBegin();" << endl; + indent(out) << "TList " << obj << " = iprot.readListBegin();" << '\n'; } indent(out) << prefix << " = new " << type_name(ttype, false, true) // size the collection correctly << "(" << (ttype->is_list() ? "" : "2*") << obj << ".size" - << ");" << endl; + << ");" << '\n'; // For loop iterates over elements string i = tmp("_i"); indent(out) << "for (int " << i << " = 0; " << i << " < " << obj << ".size" << "; " - << "++" << i << ")" << endl; + << "++" << i << ")" << '\n'; scope_up(out); @@ -2515,11 +2513,11 @@ void t_javame_generator::generate_deserialize_container(ostream& out, // Read container end if (ttype->is_map()) { - indent(out) << "iprot.readMapEnd();" << endl; + indent(out) << "iprot.readMapEnd();" << '\n'; } else if (ttype->is_set()) { - indent(out) << "iprot.readSetEnd();" << endl; + indent(out) << "iprot.readSetEnd();" << '\n'; } else if (ttype->is_list()) { - indent(out) << "iprot.readListEnd();" << endl; + indent(out) << "iprot.readListEnd();" << '\n'; } scope_down(out); @@ -2536,14 +2534,14 @@ void t_javame_generator::generate_deserialize_map_element(ostream& out, t_field fkey(tmap->get_key_type(), key); t_field fval(tmap->get_val_type(), val); - indent(out) << declare_field(&fkey) << endl; - indent(out) << declare_field(&fval) << endl; + indent(out) << declare_field(&fkey) << '\n'; + indent(out) << declare_field(&fval) << '\n'; generate_deserialize_field(out, &fkey); generate_deserialize_field(out, &fval); indent(out) << prefix << ".put(" << box_type(tmap->get_key_type(), key) << ", " - << box_type(tmap->get_val_type(), val) << ");" << endl; + << box_type(tmap->get_val_type(), val) << ");" << '\n'; } /** @@ -2555,12 +2553,12 @@ void t_javame_generator::generate_deserialize_set_element(ostream& out, string elem = tmp("_elem"); t_field felem(tset->get_elem_type(), elem); - indent(out) << declare_field(&felem) << endl; + indent(out) << declare_field(&felem) << '\n'; generate_deserialize_field(out, &felem); indent(out) << prefix << ".put(" << box_type(tset->get_elem_type(), elem) << ", " - << box_type(tset->get_elem_type(), elem) << ");" << endl; + << box_type(tset->get_elem_type(), elem) << ");" << '\n'; } /** @@ -2572,11 +2570,11 @@ void t_javame_generator::generate_deserialize_list_element(ostream& out, string elem = tmp("_elem"); t_field felem(tlist->get_elem_type(), elem); - indent(out) << declare_field(&felem) << endl; + indent(out) << declare_field(&felem) << '\n'; generate_deserialize_field(out, &felem); - indent(out) << prefix << ".addElement(" << box_type(tlist->get_elem_type(), elem) << ");" << endl; + indent(out) << prefix << ".addElement(" << box_type(tlist->get_elem_type(), elem) << ");" << '\n'; } /** @@ -2598,7 +2596,7 @@ void t_javame_generator::generate_serialize_field(ostream& out, t_field* tfield, } else if (type->is_container()) { generate_serialize_container(out, type, prefix + tfield->get_name()); } else if (type->is_enum()) { - indent(out) << "oprot.writeI32(" << prefix + tfield->get_name() << ".getValue());" << endl; + indent(out) << "oprot.writeI32(" << prefix + tfield->get_name() << ".getValue());" << '\n'; } else if (type->is_base_type()) { string name = prefix + tfield->get_name(); indent(out) << "oprot."; @@ -2640,7 +2638,7 @@ void t_javame_generator::generate_serialize_field(ostream& out, t_field* tfield, } else if (type->is_enum()) { out << "writeI32(" << name << ");"; } - out << endl; + out << '\n'; } else { printf("DO NOT KNOW HOW TO SERIALIZE FIELD '%s%s' TYPE '%s'\n", prefix.c_str(), @@ -2659,7 +2657,7 @@ void t_javame_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix) { (void)tstruct; - out << indent() << prefix << ".write(oprot);" << endl; + out << indent() << prefix << ".write(oprot);" << '\n'; } /** @@ -2674,14 +2672,14 @@ void t_javame_generator::generate_serialize_container(ostream& out, t_type* ttyp if (ttype->is_map()) { indent(out) << "oprot.writeMapBegin(new TMap(" << type_to_enum(((t_map*)ttype)->get_key_type()) << ", " << type_to_enum(((t_map*)ttype)->get_val_type()) << ", " << prefix - << ".size()));" << endl; + << ".size()));" << '\n'; } else if (ttype->is_set()) { indent(out) << "oprot.writeSetBegin(new TSet(" << type_to_enum(((t_set*)ttype)->get_elem_type()) - << ", " << prefix << ".size()));" << endl; + << ", " << prefix << ".size()));" << '\n'; } else if (ttype->is_list()) { indent(out) << "oprot.writeListBegin(new TList(" << type_to_enum(((t_list*)ttype)->get_elem_type()) << ", " << prefix << ".size()));" - << endl; + << '\n'; } string iter = tmp("_iter"); @@ -2692,7 +2690,7 @@ void t_javame_generator::generate_serialize_container(ostream& out, t_type* ttyp << ".hasMoreElements(); ) "; scope_up(out); indent(out) << key_type << " " << iter << " = (" << key_type << ")" << enumer - << ".nextElement();" << endl; + << ".nextElement();" << '\n'; } else if (ttype->is_set()) { string enumer = iter + "_enum"; string ele_type = type_name(((t_list*)ttype)->get_elem_type(), true); @@ -2700,7 +2698,7 @@ void t_javame_generator::generate_serialize_container(ostream& out, t_type* ttyp << ".hasMoreElements(); ) "; scope_up(out); indent(out) << ele_type << " " << iter << " = (" << ele_type << ")" << enumer - << ".nextElement();" << endl; + << ".nextElement();" << '\n'; } else if (ttype->is_list()) { string enumer = iter + "_enum"; indent(out) << "for (Enumeration " << enumer << " = " << prefix << ".elements(); " << enumer @@ -2708,7 +2706,7 @@ void t_javame_generator::generate_serialize_container(ostream& out, t_type* ttyp scope_up(out); string ele_type = type_name(((t_list*)ttype)->get_elem_type(), true); indent(out) << ele_type << " " << iter << " = (" << ele_type << ")" << enumer - << ".nextElement();" << endl; + << ".nextElement();" << '\n'; } if (ttype->is_map()) { @@ -2721,11 +2719,11 @@ void t_javame_generator::generate_serialize_container(ostream& out, t_type* ttyp scope_down(out); if (ttype->is_map()) { - indent(out) << "oprot.writeMapEnd();" << endl; + indent(out) << "oprot.writeMapEnd();" << '\n'; } else if (ttype->is_set()) { - indent(out) << "oprot.writeSetEnd();" << endl; + indent(out) << "oprot.writeSetEnd();" << '\n'; } else if (ttype->is_list()) { - indent(out) << "oprot.writeListEnd();" << endl; + indent(out) << "oprot.writeListEnd();" << '\n'; } scope_down(out); @@ -3056,7 +3054,7 @@ void t_javame_generator::generate_deep_copy_container(ostream& out, source_name = source_name_p1 + "." + source_name_p2; indent(out) << type_name(type, true, false) << " " << result_name << " = new " - << type_name(container, false, true) << "();" << endl; + << type_name(container, false, true) << "();" << '\n'; std::string iterator_element_name = source_name_p1 + "_element"; std::string enumeration_name = source_name_p1 + "_enum"; @@ -3067,19 +3065,19 @@ void t_javame_generator::generate_deep_copy_container(ostream& out, t_type* val_type = ((t_map*)container)->get_val_type(); indent(out) << "for (Enumeration " << enumeration_name << " = " << source_name << ".keys(); " - << enumeration_name << ".hasMoreElements(); ) {" << endl; + << enumeration_name << ".hasMoreElements(); ) {" << '\n'; indent_up(); - out << endl; + out << '\n'; indent(out) << type_name(key_type, true, false) << " " << iterator_element_name << "_key = (" << type_name(key_type, true, false) << ")" << enumeration_name << ".nextElement();" - << endl; + << '\n'; indent(out) << type_name(val_type, true, false) << " " << iterator_element_name << "_value = (" << type_name(val_type, true, false) << ")" << source_name << ".get(" - << iterator_element_name << "_key);" << endl; + << iterator_element_name << "_key);" << '\n'; - out << endl; + out << '\n'; if (key_type->is_container()) { generate_deep_copy_container(out, @@ -3093,10 +3091,10 @@ void t_javame_generator::generate_deep_copy_container(ostream& out, iterator_element_name + "_key", result_element_name + "_key", key_type); - out << ";" << endl; + out << ";" << '\n'; } - out << endl; + out << '\n'; if (val_type->is_container()) { generate_deep_copy_container(out, @@ -3110,16 +3108,16 @@ void t_javame_generator::generate_deep_copy_container(ostream& out, iterator_element_name + "_value", result_element_name + "_value", val_type); - out << ";" << endl; + out << ";" << '\n'; } - out << endl; + out << '\n'; indent(out) << result_name << ".put(" << result_element_name << "_key, " << result_element_name - << "_value);" << endl; + << "_value);" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } else { t_type* elem_type; @@ -3131,19 +3129,19 @@ void t_javame_generator::generate_deep_copy_container(ostream& out, } indent(out) << "for (Enumeration " << enumeration_name << " = " << source_name - << ".elements(); " << enumeration_name << ".hasMoreElements(); ) {" << endl; + << ".elements(); " << enumeration_name << ".hasMoreElements(); ) {" << '\n'; indent_up(); indent(out) << type_name(elem_type, true, false) << " " << iterator_element_name << " = (" << type_name(elem_type, true, false) << ")" << enumeration_name << ".nextElement();" - << endl; + << '\n'; if (elem_type->is_container()) { // recursive deep copy generate_deep_copy_container(out, iterator_element_name, "", result_element_name, elem_type); if (elem_type->is_list()) { - indent(out) << result_name << ".addElement(" << result_element_name << ");" << endl; + indent(out) << result_name << ".addElement(" << result_element_name << ");" << '\n'; } else { indent(out) << result_name << ".put(" << result_element_name << ", " << result_element_name - << ");" << endl; + << ");" << '\n'; } } else { // iterative copy @@ -3153,22 +3151,22 @@ void t_javame_generator::generate_deep_copy_container(ostream& out, iterator_element_name, "temp_binary_element", elem_type); - out << ";" << endl; + out << ";" << '\n'; if (elem_type->is_list()) { - indent(out) << result_name << ".addElement(temp_binary_element);" << endl; + indent(out) << result_name << ".addElement(temp_binary_element);" << '\n'; } else { - indent(out) << result_name << ".put(temp_binary_element, temp_binary_element);" << endl; + indent(out) << result_name << ".put(temp_binary_element, temp_binary_element);" << '\n'; } } else { indent(out) << result_name << ".addElement("; generate_deep_copy_non_container(out, iterator_element_name, result_name, elem_type); - out << ");" << endl; + out << ");" << '\n'; } } indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } } @@ -3179,7 +3177,7 @@ void t_javame_generator::generate_deep_copy_non_container(ostream& out, if (type->is_base_type() || type->is_enum() || type->is_typedef()) { // binary fields need to be copied with System.arraycopy if (type->is_binary()) { - out << "new byte[" << source_name << ".length];" << endl; + out << "new byte[" << source_name << ".length];" << '\n'; indent(out) << "System.arraycopy(" << source_name << ", 0, " << dest_name << ", 0, " << source_name << ".length)"; } @@ -3206,7 +3204,7 @@ std::string t_javame_generator::generate_isset_check(std::string field_name) { void t_javame_generator::generate_isset_set(ostream& out, t_field* field) { if (!type_can_be_null(field->get_type())) { indent(out) << "set" << get_cap_name(field->get_name()) << get_cap_name("isSet") << "(true);" - << endl; + << '\n'; } } @@ -3221,7 +3219,7 @@ std::string t_javame_generator::get_enum_class_name(t_type* type) { void t_javame_generator::generate_struct_desc(ostream& out, t_struct* tstruct) { indent(out) << "private static final TStruct STRUCT_DESC = new TStruct(\"" << tstruct->get_name() - << "\");" << endl; + << "\");" << '\n'; } void t_javame_generator::generate_field_descs(ostream& out, t_struct* tstruct) { @@ -3232,7 +3230,7 @@ void t_javame_generator::generate_field_descs(ostream& out, t_struct* tstruct) { indent(out) << "private static final TField " << constant_name((*m_iter)->get_name()) << "_FIELD_DESC = new TField(\"" << (*m_iter)->get_name() << "\", " << type_to_enum((*m_iter)->get_type()) << ", " - << "(short)" << (*m_iter)->get_key() << ");" << endl; + << "(short)" << (*m_iter)->get_key() << ");" << '\n'; } } @@ -3249,7 +3247,7 @@ bool t_javame_generator::has_bit_vector(t_struct* tstruct) { } void t_javame_generator::generate_java_struct_clear(std::ostream& out, t_struct* tstruct) { - indent(out) << "public void clear() {" << endl; + indent(out) << "public void clear() {" << '\n'; const vector& members = tstruct->get_members(); vector::const_iterator m_iter; @@ -3266,24 +3264,24 @@ void t_javame_generator::generate_java_struct_clear(std::ostream& out, t_struct* true); } else { if (type_can_be_null(t)) { - indent(out) << "this." << (*m_iter)->get_name() << " = null;" << endl; + indent(out) << "this." << (*m_iter)->get_name() << " = null;" << '\n'; } else { // must be a base type // means it also needs to be explicitly unset indent(out) << "set" << get_cap_name((*m_iter)->get_name()) << get_cap_name("isSet") - << "(false);" << endl; + << "(false);" << '\n'; switch (((t_base_type*)t)->get_base()) { case t_base_type::TYPE_I8: case t_base_type::TYPE_I16: case t_base_type::TYPE_I32: case t_base_type::TYPE_I64: - indent(out) << "this." << (*m_iter)->get_name() << " = 0;" << endl; + indent(out) << "this." << (*m_iter)->get_name() << " = 0;" << '\n'; break; case t_base_type::TYPE_DOUBLE: - indent(out) << "this." << (*m_iter)->get_name() << " = 0.0;" << endl; + indent(out) << "this." << (*m_iter)->get_name() << " = 0.0;" << '\n'; break; case t_base_type::TYPE_BOOL: - indent(out) << "this." << (*m_iter)->get_name() << " = false;" << endl; + indent(out) << "this." << (*m_iter)->get_name() << " = false;" << '\n'; break; default: // prevent gcc compiler warning break; @@ -3293,7 +3291,7 @@ void t_javame_generator::generate_java_struct_clear(std::ostream& out, t_struct* } indent_down(); - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } std::string t_javame_generator::display_name() const { diff --git a/compiler/cpp/src/thrift/generate/t_js_generator.cc b/compiler/cpp/src/thrift/generate/t_js_generator.cc index 7b0aa94c40d..2c07d9a040a 100644 --- a/compiler/cpp/src/thrift/generate/t_js_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_js_generator.cc @@ -43,7 +43,6 @@ using std::stringstream; using std::unordered_map; using std::vector; -static const string endl = "\n"; // avoid ostream << std::endl flushes static const string episode_file_name = "thrift.js.episode"; // largest consecutive integer representable by a double (2 ^ 53 - 1) static const int64_t max_safe_integer = 0x1fffffffffffff; @@ -70,6 +69,7 @@ class t_js_generator : public t_oop_generator { gen_jquery_ = false; gen_ts_ = false; gen_es6_ = false; + gen_esm_ = false; gen_episode_file_ = false; bool with_ns_ = false; @@ -87,6 +87,8 @@ class t_js_generator : public t_oop_generator { with_ns_ = true; } else if( iter->first.compare("es6") == 0) { gen_es6_ = true; + } else if ( iter->first.compare("esm") == 0) { + gen_esm_ = true; } else if( iter->first.compare("imports") == 0) { parse_imports(program, iter->second); } else if (iter->first.compare("thrift_package_output_directory") == 0) { @@ -109,6 +111,10 @@ class t_js_generator : public t_oop_generator { throw std::invalid_argument("invalid switch: [-gen js:with_ns] is only valid when using node.js"); } + if (!gen_node_ && gen_esm_) { + throw std::invalid_argument("invalid switch: [-gen js:esm] is only valid when using node.js"); + } + // Depending on the processing flags, we will update these to be ES6 compatible js_const_type_ = "var "; js_let_type_ = "var "; @@ -282,13 +288,6 @@ class t_js_generator : public t_oop_generator { return js_namespace(p); } - std::string js_export_namespace(t_program* p) { - if (gen_node_) { - return "exports."; - } - return js_namespace(p); - } - bool has_js_namespace(t_program* p) { if (no_ns_) { return false; @@ -342,17 +341,17 @@ class t_js_generator : public t_oop_generator { * @return string The documentation */ string ts_print_doc(t_doc* tdoc) { - string result = endl; + string result = "\n"; if (tdoc->has_doc()) { std::stringstream doc(tdoc->get_doc()); string item; - result += ts_indent() + "/**" + endl; + result += ts_indent() + "/**" + "\n"; while (std::getline(doc, item)) { - result += ts_indent() + " * " + item + endl; + result += ts_indent() + " * " + item + "\n"; } - result += ts_indent() + " */" + endl; + result += ts_indent() + " */" + "\n"; } return result; } @@ -383,6 +382,11 @@ class t_js_generator : public t_oop_generator { */ bool gen_es6_; + /** + * True if we should generate ES modules, instead of CommonJS. + */ + bool gen_esm_; + /** * True if we will generate an episode file. */ @@ -461,11 +465,11 @@ void t_js_generator::init_generator() { f_episode_.open(f_episode_file_path); } - const auto f_types_name = outdir + program_->get_name() + "_types.js"; + const auto f_types_name = outdir + program_->get_name() + "_types" + (gen_esm_ ? ".mjs" : ".js"); f_types_.open(f_types_name.c_str()); if (gen_episode_file_) { const auto types_module = program_->get_name() + "_types"; - f_episode_ << types_module << ":" << thrift_package_output_directory_ << "/" << types_module << endl; + f_episode_ << types_module << ":" << thrift_package_output_directory_ << "/" << types_module << '\n'; } if (gen_ts_) { @@ -477,17 +481,23 @@ void t_js_generator::init_generator() { f_types_ << autogen_comment(); if ((gen_node_ || gen_es6_) && no_ns_) { - f_types_ << "\"use strict\";" << endl << endl; + f_types_ << "\"use strict\";" << '\n' << '\n'; } - f_types_ << js_includes() << endl << render_includes() << endl; + f_types_ << js_includes() << '\n' << render_includes() << '\n'; if (gen_ts_) { - f_types_ts_ << autogen_comment() << ts_includes() << endl << render_ts_includes() << endl; + f_types_ts_ << autogen_comment() << ts_includes() << '\n' << render_ts_includes() << '\n'; } if (gen_node_) { - f_types_ << js_const_type_ << "ttypes = module.exports = {};" << endl; + if (gen_esm_) { + // Import the current module, so we can reference it as ttypes. This is + // fine in ESM, because it allows circular imports. + f_types_ << "import * as ttypes from './" + program_->get_name() + "_types.mjs';" << '\n'; + } else { + f_types_ << js_const_type_ << "ttypes = module.exports = {};" << '\n'; + } } string pns; @@ -498,11 +508,11 @@ void t_js_generator::init_generator() { if (ns_pieces.size() > 0) { for (size_t i = 0; i < ns_pieces.size(); ++i) { pns += ((i == 0) ? "" : ".") + ns_pieces[i]; - 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; + f_types_ << "if (typeof " << pns << " === 'undefined') {" << '\n'; + f_types_ << " " << pns << " = {};" << '\n'; + f_types_ << "}" << '\n'; + f_types_ << "" << "if (typeof module !== 'undefined' && module.exports) {" << '\n'; + f_types_ << " module.exports." << pns << " = " << pns << ";" << '\n' << "}" << '\n'; } if (gen_ts_) { ts_module_ = pns; @@ -516,12 +526,26 @@ void t_js_generator::init_generator() { */ string t_js_generator::js_includes() { if (gen_node_) { - string result = js_const_type_ + "thrift = require('" + gen_node_runtime_package_ + "');\n" - + js_const_type_ + "Thrift = thrift.Thrift;\n"; + string result; + + if (gen_esm_) { + result += "import { Thrift } from 'thrift';\n"; + } else { + result += js_const_type_ + "thrift = require('thrift');\n" + + js_const_type_ + "Thrift = thrift.Thrift;\n"; + } if (!gen_es6_) { - result += js_const_type_ + "Q = thrift.Q;\n"; + if (gen_esm_) { + result += "import { Q } from 'thrift';\n"; + } else { + result += js_const_type_ + "Q = thrift.Q;\n"; + } + } + if (gen_esm_) { + result += "import Int64 from 'node-int64';"; + } else { + result += js_const_type_ + "Int64 = require('node-int64');\n"; } - result += js_const_type_ + "Int64 = require('node-int64');\n"; return result; } string result = "if (typeof Int64 === 'undefined' && typeof require === 'function') {\n " + js_const_type_ + "Int64 = require('node-int64');\n}\n"; @@ -565,7 +589,11 @@ string t_js_generator::render_includes() { if (gen_node_) { const vector& includes = program_->get_includes(); for (auto include : includes) { - result += js_const_type_ + make_valid_nodeJs_identifier(include->get_name()) + "_ttypes = require('" + get_import_path(include) + "');\n"; + if (gen_esm_) { + result += "import * as " + make_valid_nodeJs_identifier(include->get_name()) + "_ttypes from '" + get_import_path(include) + "';\n"; + } else { + result += js_const_type_ + make_valid_nodeJs_identifier(include->get_name()) + "_ttypes = require('" + get_import_path(include) + "');\n"; + } } if (includes.size() > 0) { result += "\n"; @@ -599,17 +627,17 @@ string t_js_generator::render_ts_includes() { string t_js_generator::get_import_path(t_program* program) { const string import_file_name(program->get_name() + "_types"); + const string import_file_name_with_extension = import_file_name + (gen_esm_ ? ".mjs" : ".js"); + if (program->get_recursive()) { - return "./" + import_file_name; + return "./" + import_file_name_with_extension; } - const string import_file_name_with_extension = import_file_name + ".js"; - - auto module_name_and_import_path_iterator = module_name_2_import_path.find(import_file_name); - if (module_name_and_import_path_iterator != module_name_2_import_path.end()) { - return module_name_and_import_path_iterator->second; - } - return "./" + import_file_name; + auto module_name_and_import_path_iterator = module_name_2_import_path.find(import_file_name); + if (module_name_and_import_path_iterator != module_name_2_import_path.end()) { + return module_name_and_import_path_iterator->second; + } + return "./" + import_file_name_with_extension; } /** @@ -647,11 +675,15 @@ void t_js_generator::generate_typedef(t_typedef* ttypedef) { * @param tenum The enumeration */ void t_js_generator::generate_enum(t_enum* tenum) { - f_types_ << js_type_namespace(tenum->get_program()) << tenum->get_name() << " = {" << endl; + if (gen_esm_) { + f_types_ << "export const " << tenum->get_name() << " = {" << '\n'; + } else { + f_types_ << js_type_namespace(tenum->get_program()) << tenum->get_name() << " = {" << '\n'; + } if (gen_ts_) { f_types_ts_ << ts_print_doc(tenum) << ts_indent() << ts_declare() << "enum " - << tenum->get_name() << " {" << endl; + << tenum->get_name() << " {" << '\n'; } indent_up(); @@ -661,23 +693,23 @@ void t_js_generator::generate_enum(t_enum* tenum) { for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) { int value = (*c_iter)->get_value(); if (gen_ts_) { - f_types_ts_ << ts_indent() << (*c_iter)->get_name() << " = " << value << "," << endl; + f_types_ts_ << ts_indent() << (*c_iter)->get_name() << " = " << value << "," << '\n'; // add 'value: key' in addition to 'key: value' for TypeScript enums - f_types_ << indent() << "'" << value << "' : '" << (*c_iter)->get_name() << "'," << endl; + f_types_ << indent() << "'" << value << "' : '" << (*c_iter)->get_name() << "'," << '\n'; } f_types_ << indent() << "'" << (*c_iter)->get_name() << "' : " << value; if (c_iter != constants.end() - 1) { f_types_ << ","; } - f_types_ << endl; + f_types_ << '\n'; } indent_down(); - f_types_ << "};" << endl; + f_types_ << "};" << '\n'; if (gen_ts_) { - f_types_ts_ << ts_indent() << "}" << endl; + f_types_ts_ << ts_indent() << "}" << '\n'; } } @@ -689,12 +721,16 @@ void t_js_generator::generate_const(t_const* tconst) { string name = tconst->get_name(); t_const_value* value = tconst->get_value(); - f_types_ << js_type_namespace(program_) << name << " = "; - f_types_ << render_const_value(type, value) << ";" << endl; + if (gen_esm_) { + f_types_ << "export const " << name << " = "; + } else { + f_types_ << js_type_namespace(program_) << name << " = "; + } + f_types_ << render_const_value(type, value) << ";" << '\n'; if (gen_ts_) { f_types_ts_ << ts_print_doc(tconst) << ts_indent() << ts_declare() << js_const_type_ << name << ": " - << ts_get_type(type) << ";" << endl; + << ts_get_type(type) << ";" << '\n'; } } @@ -763,24 +799,24 @@ string t_js_generator::render_const_value(t_type* type, t_const_value* value) { } if (v_iter != val.begin()) out << ","; - out << endl << indent() << render_const_value(g_type_string, v_iter->first); + out << '\n' << indent() << render_const_value(g_type_string, v_iter->first); out << " : "; out << render_const_value(field_type, v_iter->second); } indent_down(); - out << endl << indent() << "})"; + out << '\n' << indent() << "})"; } else if (type->is_map()) { t_type* ktype = ((t_map*)type)->get_key_type(); t_type* vtype = ((t_map*)type)->get_val_type(); - out << "{" << endl; + out << "{" << '\n'; indent_up(); const map& val = value->get_map(); map::const_iterator v_iter; for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { if (v_iter != val.begin()) - out << "," << endl; + out << "," << '\n'; 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() << "\""; @@ -792,7 +828,7 @@ string t_js_generator::render_const_value(t_type* type, t_const_value* value) { out << render_const_value(vtype, v_iter->second); } indent_down(); - out << endl << indent() << "}"; + out << '\n' << indent() << "}"; } else if (type->is_list() || type->is_set()) { t_type* etype; if (type->is_list()) { @@ -868,33 +904,42 @@ void t_js_generator::generate_js_struct_definition(ostream& out, vector::const_iterator m_iter; if (gen_node_) { + string commonjs_export = ""; + + if (is_exported) { + if (gen_esm_) { + out << "export "; + } else { + commonjs_export = " = module.exports." + tstruct->get_name(); + } + } + string prefix = has_js_namespace(tstruct->get_program()) ? js_namespace(tstruct->get_program()) : js_const_type_; - out << prefix << tstruct->get_name() << - (is_exported ? " = module.exports." + tstruct->get_name() : ""); + out << prefix << tstruct->get_name() << commonjs_export; if (gen_ts_) { f_types_ts_ << ts_print_doc(tstruct) << ts_indent() << ts_declare() << "class " << tstruct->get_name() << (is_exception ? " extends Thrift.TException" : "") - << " {" << endl; + << " {" << '\n'; } } else { out << js_namespace(tstruct->get_program()) << tstruct->get_name(); if (gen_ts_) { f_types_ts_ << ts_print_doc(tstruct) << ts_indent() << ts_declare() << "class " << tstruct->get_name() << (is_exception ? " extends Thrift.TException" : "") - << " {" << endl; + << " {" << '\n'; } } if (gen_es6_) { if (gen_node_ && is_exception) { - out << " = class extends Thrift.TException {" << endl; + out << " = class extends Thrift.TException {" << '\n'; } else { - out << " = class {" << endl; + out << " = class {" << '\n'; } indent_up(); - indent(out) << "constructor(args) {" << endl; + indent(out) << "constructor(args) {" << '\n'; } else { - out << " = function(args) {" << endl; + out << " = function(args) {" << '\n'; } indent_up(); @@ -902,13 +947,13 @@ void t_js_generator::generate_js_struct_definition(ostream& out, // Call super() method on inherited Error class if (gen_node_ && is_exception) { if (gen_es6_) { - indent(out) << "super(args);" << endl; + indent(out) << "super(args);" << '\n'; } else { indent(out) << "Thrift.TException.call(this, \"" << js_namespace(tstruct->get_program()) - << tstruct->get_name() << "\");" << endl; + << tstruct->get_name() << "\");" << '\n'; } out << indent() << "this.name = \"" << js_namespace(tstruct->get_program()) - << tstruct->get_name() << "\";" << endl; + << tstruct->get_name() << "\";" << '\n'; } // members with arguments @@ -917,9 +962,9 @@ void t_js_generator::generate_js_struct_definition(ostream& out, t_type* t = get_true_type((*m_iter)->get_type()); if ((*m_iter)->get_value() != nullptr && !(t->is_struct() || t->is_xception())) { dval = render_const_value((*m_iter)->get_type(), (*m_iter)->get_value()); - out << indent() << "this." << (*m_iter)->get_name() << " = " << dval << ";" << endl; + out << indent() << "this." << (*m_iter)->get_name() << " = " << dval << ";" << '\n'; } else { - out << indent() << dval << ";" << endl; + out << indent() << dval << ";" << '\n'; } if (gen_ts_) { string ts_access = gen_node_ ? "public " : ""; @@ -927,11 +972,11 @@ void t_js_generator::generate_js_struct_definition(ostream& out, // Special case. Exceptions derive from Error, and error has a non optional message field. // Ignore the optional flag in this case, otherwise we will generate a incompatible field - // in the eyes of typescript. + // in the eyes of typescript. string optional_flag = is_exception && member_name == "message" ? "" : ts_get_req(*m_iter); - + f_types_ts_ << ts_indent() << ts_access << member_name << optional_flag << ": " - << ts_get_type((*m_iter)->get_type()) << ";" << endl; + << ts_get_type((*m_iter)->get_type()) << ";" << '\n'; } } @@ -942,7 +987,7 @@ void t_js_generator::generate_js_struct_definition(ostream& out, t_type* t = get_true_type((*m_iter)->get_type()); if ((*m_iter)->get_value() != nullptr && (t->is_struct() || t->is_xception())) { indent(out) << "this." << (*m_iter)->get_name() << " = " - << render_const_value(t, (*m_iter)->get_value()) << ";" << endl; + << render_const_value(t, (*m_iter)->get_value()) << ";" << '\n'; } } @@ -951,28 +996,28 @@ void t_js_generator::generate_js_struct_definition(ostream& out, t_type* t = get_true_type((*m_iter)->get_type()); if (t->is_xception()) { out << indent() << "if (args instanceof " << js_type_namespace(t->get_program()) - << t->get_name() << ") {" << endl << indent() << indent() << "this." - << (*m_iter)->get_name() << " = args;" << endl << indent() << indent() << "return;" - << endl << indent() << "}" << endl; + << t->get_name() << ") {" << '\n' << indent() << indent() << "this." + << (*m_iter)->get_name() << " = args;" << '\n' << indent() << indent() << "return;" + << '\n' << indent() << "}" << '\n'; } } - indent(out) << "if (args) {" << endl; + indent(out) << "if (args) {" << '\n'; indent_up(); if (gen_ts_) { - f_types_ts_ << endl << ts_indent() << "constructor(args?: { "; + f_types_ts_ << '\n' << ts_indent() << "constructor(args?: { "; } for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { t_type* t = get_true_type((*m_iter)->get_type()); - indent(out) << "if (args." << (*m_iter)->get_name() << " !== undefined && args." << (*m_iter)->get_name() << " !== null) {" << endl; + indent(out) << "if (args." << (*m_iter)->get_name() << " !== undefined && args." << (*m_iter)->get_name() << " !== null) {" << '\n'; indent_up(); indent(out) << "this." << (*m_iter)->get_name(); if (t->is_struct()) { out << (" = new " + js_type_namespace(t->get_program()) + t->get_name() + "(args."+(*m_iter)->get_name() +");"); - out << endl; + out << '\n'; } else if (t->is_container()) { t_type* etype = get_contained_type(t); string copyFunc = t->is_map() ? "Thrift.copyMap" : "Thrift.copyList"; @@ -1001,53 +1046,53 @@ void t_js_generator::generate_js_struct_definition(ostream& out, out << (" = " + copyFunc + "(args." + (*m_iter)->get_name() + ", [" + type_list + "]);"); - out << endl; + out << '\n'; } else { - out << " = args." << (*m_iter)->get_name() << ";" << endl; + out << " = args." << (*m_iter)->get_name() << ";" << '\n'; } indent_down(); if (!(*m_iter)->get_req()) { - indent(out) << "} else {" << endl; + indent(out) << "} else {" << '\n'; indent(out) << " throw new Thrift.TProtocolException(Thrift.TProtocolExceptionType.UNKNOWN, " - "'Required field " << (*m_iter)->get_name() << " is unset!');" << endl; + "'Required field " << (*m_iter)->get_name() << " is unset!');" << '\n'; } - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; if (gen_ts_) { f_types_ts_ << (*m_iter)->get_name() << ts_get_req(*m_iter) << ": " << ts_get_type((*m_iter)->get_type()) << "; "; } } indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; if (gen_ts_) { - f_types_ts_ << "});" << endl; + f_types_ts_ << "});" << '\n'; } } // Done with constructor indent_down(); if (gen_es6_) { - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } else { - indent(out) << "};" << endl; + indent(out) << "};" << '\n'; } if (gen_ts_) { - f_types_ts_ << ts_indent() << "}" << endl; + f_types_ts_ << ts_indent() << "}" << '\n'; } if (!gen_es6_) { if (is_exception) { out << "Thrift.inherits(" << js_namespace(tstruct->get_program()) << tstruct->get_name() - << ", Thrift.TException);" << endl; + << ", Thrift.TException);" << '\n'; out << js_namespace(tstruct->get_program()) << tstruct->get_name() << ".prototype.name = '" - << tstruct->get_name() << "';" << endl; + << tstruct->get_name() << "';" << '\n'; } else { // init prototype manually if we aren't using es6 out << js_namespace(tstruct->get_program()) << tstruct->get_name() << ".prototype = {};" - << endl; + << '\n'; } } @@ -1058,7 +1103,7 @@ void t_js_generator::generate_js_struct_definition(ostream& out, // Close out the class definition if (gen_es6_) { indent_down(); - indent(out) << "};" << endl; + indent(out) << "};" << '\n'; } } @@ -1070,84 +1115,84 @@ void t_js_generator::generate_js_struct_reader(ostream& out, t_struct* tstruct) vector::const_iterator f_iter; if (gen_es6_) { - indent(out) << "read (input) {" << endl; + indent(out) << "[Symbol.for(\"read\")] (input) {" << '\n'; } else { indent(out) << js_namespace(tstruct->get_program()) << tstruct->get_name() - << ".prototype.read = function(input) {" << endl; + << ".prototype[Symbol.for(\"read\")] = function(input) {" << '\n'; } indent_up(); - indent(out) << "input.readStructBegin();" << endl; + indent(out) << "input.readStructBegin();" << '\n'; // Loop over reading in fields - indent(out) << "while (true) {" << endl; + indent(out) << "while (true) {" << '\n'; indent_up(); - indent(out) << js_const_type_ << "ret = input.readFieldBegin();" << endl; - indent(out) << js_const_type_ << "ftype = ret.ftype;" << endl; + indent(out) << js_const_type_ << "ret = input.readFieldBegin();" << '\n'; + indent(out) << js_const_type_ << "ftype = ret.ftype;" << '\n'; if (!fields.empty()) { - indent(out) << js_const_type_ << "fid = ret.fid;" << endl; + indent(out) << js_const_type_ << "fid = ret.fid;" << '\n'; } // Check for field STOP marker and break - indent(out) << "if (ftype == Thrift.Type.STOP) {" << endl; + indent(out) << "if (ftype == Thrift.Type.STOP) {" << '\n'; indent_up(); - indent(out) << "break;" << endl; + indent(out) << "break;" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; if (!fields.empty()) { // Switch statement on the field we are reading - indent(out) << "switch (fid) {" << endl; + indent(out) << "switch (fid) {" << '\n'; indent_up(); // 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(out) << "if (ftype == " << type_to_enum((*f_iter)->get_type()) << ") {" << endl; + indent(out) << "case " << (*f_iter)->get_key() << ":" << '\n'; + indent(out) << "if (ftype == " << type_to_enum((*f_iter)->get_type()) << ") {" << '\n'; indent_up(); generate_deserialize_field(out, *f_iter, "this."); indent_down(); - indent(out) << "} else {" << endl; + indent(out) << "} else {" << '\n'; - indent(out) << " input.skip(ftype);" << endl; + indent(out) << " input.skip(ftype);" << '\n'; - out << indent() << "}" << endl << indent() << "break;" << endl; + out << indent() << "}" << '\n' << indent() << "break;" << '\n'; } if (fields.size() == 1) { // pseudo case to make jslint happy - indent(out) << "case 0:" << endl; - indent(out) << " input.skip(ftype);" << endl; - indent(out) << " break;" << endl; + indent(out) << "case 0:" << '\n'; + indent(out) << " input.skip(ftype);" << '\n'; + indent(out) << " break;" << '\n'; } // In the default case we skip the field - indent(out) << "default:" << endl; - indent(out) << " input.skip(ftype);" << endl; + indent(out) << "default:" << '\n'; + indent(out) << " input.skip(ftype);" << '\n'; scope_down(out); } else { - indent(out) << "input.skip(ftype);" << endl; + indent(out) << "input.skip(ftype);" << '\n'; } - indent(out) << "input.readFieldEnd();" << endl; + indent(out) << "input.readFieldEnd();" << '\n'; scope_down(out); - indent(out) << "input.readStructEnd();" << endl; + indent(out) << "input.readStructEnd();" << '\n'; - indent(out) << "return;" << endl; + indent(out) << "return;" << '\n'; indent_down(); if (gen_es6_) { - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } else { - indent(out) << "};" << endl << endl; + indent(out) << "};" << '\n' << '\n'; } } @@ -1160,44 +1205,44 @@ void t_js_generator::generate_js_struct_writer(ostream& out, t_struct* tstruct) vector::const_iterator f_iter; if (gen_es6_) { - indent(out) << "write (output) {" << endl; + indent(out) << "[Symbol.for(\"write\")] (output) {" << '\n'; } else { indent(out) << js_namespace(tstruct->get_program()) << tstruct->get_name() - << ".prototype.write = function(output) {" << endl; + << ".prototype[Symbol.for(\"write\")] = function(output) {" << '\n'; } indent_up(); - indent(out) << "output.writeStructBegin('" << name << "');" << endl; + indent(out) << "output.writeStructBegin('" << name << "');" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { out << indent() << "if (this." << (*f_iter)->get_name() << " !== null && this." - << (*f_iter)->get_name() << " !== undefined) {" << endl; + << (*f_iter)->get_name() << " !== undefined) {" << '\n'; indent_up(); indent(out) << "output.writeFieldBegin(" << "'" << (*f_iter)->get_name() << "', " << type_to_enum((*f_iter)->get_type()) - << ", " << (*f_iter)->get_key() << ");" << endl; + << ", " << (*f_iter)->get_key() << ");" << '\n'; // Write field contents generate_serialize_field(out, *f_iter, "this."); - indent(out) << "output.writeFieldEnd();" << endl; + indent(out) << "output.writeFieldEnd();" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } - out << indent() << "output.writeFieldStop();" << endl << indent() << "output.writeStructEnd();" - << endl; + out << indent() << "output.writeFieldStop();" << '\n' << indent() << "output.writeStructEnd();" + << '\n'; - out << indent() << "return;" << endl; + out << indent() << "return;" << '\n'; indent_down(); if (gen_es6_) { - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } else { - out << indent() << "};" << endl << endl; + out << indent() << "};" << '\n' << '\n'; } } @@ -1207,10 +1252,10 @@ void t_js_generator::generate_js_struct_writer(ostream& out, t_struct* tstruct) * @param tservice The service definition */ void t_js_generator::generate_service(t_service* tservice) { - string f_service_name = get_out_dir() + service_name_ + ".js"; + string f_service_name = get_out_dir() + service_name_ + (gen_esm_ ? ".mjs" : ".js"); f_service_.open(f_service_name.c_str()); if (gen_episode_file_) { - f_episode_ << service_name_ << ":" << thrift_package_output_directory_ << "/" << service_name_ << endl; + f_episode_ << service_name_ << ":" << thrift_package_output_directory_ << "/" << service_name_ << '\n'; } if (gen_ts_) { @@ -1221,58 +1266,58 @@ void t_js_generator::generate_service(t_service* tservice) { f_service_ << autogen_comment(); if ((gen_node_ || gen_es6_) && no_ns_) { - f_service_ << "\"use strict\";" << endl << endl; + f_service_ << "\"use strict\";" << '\n' << '\n'; } - f_service_ << js_includes() << endl << render_includes() << endl; + f_service_ << js_includes() << '\n' << render_includes() << '\n'; if (gen_ts_) { if (tservice->get_extends() != nullptr) { f_service_ts_ << "/// get_extends()->get_name() - << ".d.ts\" />" << endl; + << ".d.ts\" />" << '\n'; } - f_service_ts_ << autogen_comment() << endl << ts_includes() << endl << render_ts_includes() << endl; + f_service_ts_ << autogen_comment() << '\n' << ts_includes() << '\n' << render_ts_includes() << '\n'; if (gen_node_) { - f_service_ts_ << "import ttypes = require('./" + program_->get_name() + "_types');" << endl; + f_service_ts_ << "import ttypes = require('./" + program_->get_name() + "_types');" << '\n'; // Generate type aliases // enum vector const& enums = program_->get_enums(); vector::const_iterator e_iter; for (e_iter = enums.begin(); e_iter != enums.end(); ++e_iter) { f_service_ts_ << "import " << (*e_iter)->get_name() << " = ttypes." - << js_namespace(program_) << (*e_iter)->get_name() << endl; + << js_namespace(program_) << (*e_iter)->get_name() << '\n'; } // const vector const& consts = program_->get_consts(); vector::const_iterator c_iter; for (c_iter = consts.begin(); c_iter != consts.end(); ++c_iter) { f_service_ts_ << "import " << (*c_iter)->get_name() << " = ttypes." - << js_namespace(program_) << (*c_iter)->get_name() << endl; + << js_namespace(program_) << (*c_iter)->get_name() << '\n'; } // exception vector const& exceptions = program_->get_xceptions(); vector::const_iterator x_iter; for (x_iter = exceptions.begin(); x_iter != exceptions.end(); ++x_iter) { f_service_ts_ << "import " << (*x_iter)->get_name() << " = ttypes." - << js_namespace(program_) << (*x_iter)->get_name() << endl; + << js_namespace(program_) << (*x_iter)->get_name() << '\n'; } // structs vector const& structs = program_->get_structs(); vector::const_iterator s_iter; for (s_iter = structs.begin(); s_iter != structs.end(); ++s_iter) { f_service_ts_ << "import " << (*s_iter)->get_name() << " = ttypes." - << js_namespace(program_) << (*s_iter)->get_name() << endl; + << js_namespace(program_) << (*s_iter)->get_name() << '\n'; } } else { - f_service_ts_ << "import { " << program_->get_name() << " } from \"./" << program_->get_name() << "_types\";" << endl << endl; + f_service_ts_ << "import { " << program_->get_name() << " } from \"./" << program_->get_name() << "_types\";" << '\n' << '\n'; } if (!ts_module_.empty()) { if (gen_node_) { f_service_ts_ << "declare module " << ts_module_ << " {"; } else { - f_service_ts_ << "declare module \"./" << program_->get_name() << "_types\" {" << endl; + f_service_ts_ << "declare module \"./" << program_->get_name() << "_types\" {" << '\n'; indent_up(); - f_service_ts_ << ts_indent() << "module " << program_->get_name() << " {" << endl; + f_service_ts_ << ts_indent() << "module " << program_->get_name() << " {" << '\n'; indent_up(); } } @@ -1281,17 +1326,21 @@ void t_js_generator::generate_service(t_service* tservice) { if (gen_node_) { if (tservice->get_extends() != nullptr) { f_service_ << js_const_type_ << tservice->get_extends()->get_name() << " = require('./" - << tservice->get_extends()->get_name() << "');" << endl << js_const_type_ + << tservice->get_extends()->get_name() << "');" << '\n' << js_const_type_ << tservice->get_extends()->get_name() - << "Client = " << tservice->get_extends()->get_name() << ".Client;" << endl + << "Client = " << tservice->get_extends()->get_name() << ".Client;" << '\n' << js_const_type_ << tservice->get_extends()->get_name() - << "Processor = " << tservice->get_extends()->get_name() << ".Processor;" << endl; + << "Processor = " << tservice->get_extends()->get_name() << ".Processor;" << '\n'; f_service_ts_ << "import " << tservice->get_extends()->get_name() << " = require('./" - << tservice->get_extends()->get_name() << "');" << endl; + << tservice->get_extends()->get_name() << "');" << '\n'; } - f_service_ << js_const_type_ << "ttypes = require('./" + program_->get_name() + "_types');" << endl; + if (gen_esm_) { + f_service_ << "import * as ttypes from './" + program_->get_name() + "_types.mjs';" << '\n'; + } else { + f_service_ << js_const_type_ << "ttypes = require('./" + program_->get_name() + "_types');" << '\n'; + } } generate_service_helpers(tservice); @@ -1306,11 +1355,11 @@ void t_js_generator::generate_service(t_service* tservice) { if (gen_ts_) { if (!ts_module_.empty()) { if (gen_node_) { - f_service_ts_ << "}" << endl; + f_service_ts_ << "}" << '\n'; } else { indent_down(); - f_service_ts_ << ts_indent() << "}" << endl; - f_service_ts_ << "}" << endl; + f_service_ts_ << ts_indent() << "}" << '\n'; + f_service_ts_ << "}" << '\n'; } } f_service_ts_.close(); @@ -1326,27 +1375,28 @@ void t_js_generator::generate_service_processor(t_service* tservice) { vector functions = tservice->get_functions(); vector::iterator f_iter; - if (gen_node_) { - string prefix = has_js_namespace(tservice->get_program()) ? js_namespace(tservice->get_program()) : js_const_type_; - f_service_ << prefix << service_name_ << "Processor = " << "exports.Processor"; - if (gen_ts_) { - f_service_ts_ << endl << "declare class Processor "; - if (tservice->get_extends() != nullptr) { - f_service_ts_ << "extends " << tservice->get_extends()->get_name() << ".Processor "; - } - f_service_ts_ << "{" << endl; - indent_up(); + std::string service_var; + if (!gen_node_ || has_js_namespace(tservice->get_program())) { + service_var = js_namespace(tservice->get_program()) + service_name_ + "Processor"; + f_service_ << service_var; + } else { + service_var = service_name_ + "Processor"; + f_service_ << js_const_type_ << service_var; + }; + if (gen_node_ && gen_ts_) { + f_service_ts_ << '\n' << "declare class Processor "; + if (tservice->get_extends() != nullptr) { + f_service_ts_ << "extends " << tservice->get_extends()->get_name() << ".Processor "; + } + f_service_ts_ << "{" << '\n'; + indent_up(); - if(tservice->get_extends() == nullptr) { - 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(); + if(tservice->get_extends() == nullptr) { + f_service_ts_ << ts_indent() << "private _handler: object;" << '\n' << '\n'; } - } else { - f_service_ << js_namespace(tservice->get_program()) << service_name_ << "Processor = " - << "exports.Processor"; + f_service_ts_ << ts_indent() << "constructor(handler: object);" << '\n'; + f_service_ts_ << ts_indent() << "process(input: thrift.TProtocol, output: thrift.TProtocol): void;" << '\n'; + indent_down(); } bool is_subclass_service = tservice->get_extends() != nullptr; @@ -1354,65 +1404,65 @@ void t_js_generator::generate_service_processor(t_service* tservice) { // ES6 Constructor if (gen_es6_) { if (is_subclass_service) { - f_service_ << " = class " << service_name_ << "Processor extends " << tservice->get_extends()->get_name() << "Processor {" << endl; + f_service_ << " = class " << service_name_ << "Processor extends " << tservice->get_extends()->get_name() << "Processor {" << '\n'; } else { - f_service_ << " = class " << service_name_ << "Processor {" << endl; + f_service_ << " = class " << service_name_ << "Processor {" << '\n'; } indent_up(); - indent(f_service_) << "constructor(handler) {" << endl; + indent(f_service_) << "constructor(handler) {" << '\n'; } else { - f_service_ << " = function(handler) {" << endl; + f_service_ << " = function(handler) {" << '\n'; } indent_up(); if (gen_es6_ && is_subclass_service) { - indent(f_service_) << "super(handler);" << endl; + indent(f_service_) << "super(handler);" << '\n'; } - indent(f_service_) << "this._handler = handler;" << endl; + indent(f_service_) << "this._handler = handler;" << '\n'; indent_down(); // Done with constructor if (gen_es6_) { - indent(f_service_) << "}" << endl; + indent(f_service_) << "}" << '\n'; } else { - indent(f_service_) << "};" << endl; + indent(f_service_) << "};" << '\n'; } // ES5 service inheritance if (!gen_es6_ && is_subclass_service) { indent(f_service_) << "Thrift.inherits(" << js_namespace(tservice->get_program()) << service_name_ << "Processor, " << tservice->get_extends()->get_name() - << "Processor);" << endl; + << "Processor);" << '\n'; } // Generate the server implementation if (gen_es6_) { - indent(f_service_) << "process (input, output) {" << endl; + indent(f_service_) << "process (input, output) {" << '\n'; } else { indent(f_service_) << js_namespace(tservice->get_program()) << service_name_ - << "Processor.prototype.process = function(input, output) {" << endl; + << "Processor.prototype.process = function(input, output) {" << '\n'; } indent_up(); - indent(f_service_) << js_const_type_ << "r = input.readMessageBegin();" << endl << indent() - << "if (this['process_' + r.fname]) {" << endl << indent() - << " return this['process_' + r.fname].call(this, r.rseqid, input, output);" << endl - << indent() << "} else {" << endl << indent() << " input.skip(Thrift.Type.STRUCT);" - << endl << indent() << " input.readMessageEnd();" << endl << indent() + indent(f_service_) << js_const_type_ << "r = input.readMessageBegin();" << '\n' << indent() + << "if (this['process_' + r.fname]) {" << '\n' << indent() + << " return this['process_' + r.fname].call(this, r.rseqid, input, output);" << '\n' + << indent() << "} else {" << '\n' << indent() << " input.skip(Thrift.Type.STRUCT);" + << '\n' << indent() << " input.readMessageEnd();" << '\n' << indent() << " " << js_const_type_ << "x = new " "Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN_METHOD, " - "'Unknown function ' + r.fname);" << endl << indent() + "'Unknown function ' + r.fname);" << '\n' << indent() << " output.writeMessageBegin(r.fname, Thrift.MessageType.EXCEPTION, r.rseqid);" - << endl << indent() << " x.write(output);" << endl << indent() - << " output.writeMessageEnd();" << endl << indent() << " output.flush();" << endl - << indent() << "}" << endl; + << '\n' << indent() << " x[Symbol.for(\"write\")](output);" << '\n' << indent() + << " output.writeMessageEnd();" << '\n' << indent() << " output.flush();" << '\n' + << indent() << "}" << '\n'; indent_down(); if (gen_es6_) { - indent(f_service_) << "}" << endl; + indent(f_service_) << "}" << '\n'; } else { - indent(f_service_) << "};" << endl; + indent(f_service_) << "};" << '\n'; } // Generate the process subfunctions @@ -1423,10 +1473,16 @@ void t_js_generator::generate_service_processor(t_service* tservice) { // Close off the processor class definition if (gen_es6_) { indent_down(); - indent(f_service_) << "};" << endl; + indent(f_service_) << "};" << '\n'; } if (gen_node_ && gen_ts_) { - f_service_ts_ << "}" << endl; + f_service_ts_ << "}" << '\n'; + } + + if(gen_esm_) { + f_service_ << "export { " << service_var << " as Processor };" << '\n'; + } else { + f_service_ << "exports.Processor = " << service_var << ";" << '\n'; } } @@ -1437,15 +1493,15 @@ void t_js_generator::generate_service_processor(t_service* tservice) { */ void t_js_generator::generate_process_function(t_service* tservice, t_function* tfunction) { if (gen_es6_) { - indent(f_service_) << "process_" + tfunction->get_name() + " (seqid, input, output) {" << endl; + indent(f_service_) << "process_" + tfunction->get_name() + " (seqid, input, output) {" << '\n'; } else { indent(f_service_) << js_namespace(tservice->get_program()) << service_name_ << "Processor.prototype.process_" + tfunction->get_name() - + " = function(seqid, input, output) {" << endl; + + " = function(seqid, input, output) {" << '\n'; } if (gen_ts_) { indent_up(); - f_service_ts_ << ts_indent() << "process_" << tfunction->get_name() << "(seqid: number, input: thrift.TProtocol, output: thrift.TProtocol): void;" << endl; + f_service_ts_ << ts_indent() << "process_" << tfunction->get_name() << "(seqid: number, input: thrift.TProtocol, output: thrift.TProtocol): void;" << '\n'; indent_down(); } @@ -1455,8 +1511,8 @@ void t_js_generator::generate_process_function(t_service* tservice, t_function* string resultname = js_namespace(program_) + service_name_ + "_" + tfunction->get_name() + "_result"; - indent(f_service_) << js_const_type_ << "args = new " << argsname << "();" << endl << indent() - << "args.read(input);" << endl << indent() << "input.readMessageEnd();" << endl; + indent(f_service_) << js_const_type_ << "args = new " << argsname << "();" << '\n' << indent() + << "args[Symbol.for(\"read\")](input);" << '\n' << indent() << "input.readMessageEnd();" << '\n'; // Generate the function call t_struct* arg_struct = tfunction->get_arglist(); @@ -1477,58 +1533,58 @@ void t_js_generator::generate_process_function(t_service* tservice, t_function* f_service_ << "args." << (*f_iter)->get_name(); } - f_service_ << ");" << endl; + f_service_ << ");" << '\n'; indent_down(); if (gen_es6_) { - indent(f_service_) << "}" << endl; + indent(f_service_) << "}" << '\n'; } else { - indent(f_service_) << "};" << endl; + indent(f_service_) << "};" << '\n'; } return; } // Promise style invocation indent(f_service_) << "if (this._handler." << tfunction->get_name() - << ".length === " << fields.size() << ") {" << endl; + << ".length === " << fields.size() << ") {" << '\n'; indent_up(); if (gen_es6_) { - indent(f_service_) << "new Promise((resolve) => resolve(this._handler." << tfunction->get_name() << ".bind(this._handler)(" << endl; + indent(f_service_) << "new Promise((resolve) => resolve(this._handler." << tfunction->get_name() << ".bind(this._handler)(" << '\n'; } else { string maybeComma = (fields.size() > 0 ? "," : ""); indent(f_service_) << "Q.fcall(this._handler." << tfunction->get_name() << ".bind(this._handler)" - << maybeComma << endl; + << maybeComma << '\n'; } indent_up(); for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { string maybeComma = (f_iter != fields.end() - 1 ? "," : ""); - indent(f_service_) << "args." << (*f_iter)->get_name() << maybeComma << endl; + indent(f_service_) << "args." << (*f_iter)->get_name() << maybeComma << '\n'; } indent_down(); if (gen_es6_) { - indent(f_service_) << "))).then(result => {" << endl; + indent(f_service_) << "))).then(result => {" << '\n'; } else { - indent(f_service_) << ").then(function(result) {" << endl; + indent(f_service_) << ").then(function(result) {" << '\n'; } indent_up(); - f_service_ << indent() << js_const_type_ << "result_obj = new " << resultname << "({success: result});" << endl + f_service_ << indent() << js_const_type_ << "result_obj = new " << resultname << "({success: result});" << '\n' << indent() << "output.writeMessageBegin(\"" << tfunction->get_name() - << "\", Thrift.MessageType.REPLY, seqid);" << endl << indent() - << "result_obj.write(output);" << endl << indent() << "output.writeMessageEnd();" << endl - << indent() << "output.flush();" << endl; + << "\", Thrift.MessageType.REPLY, seqid);" << '\n' << indent() + << "result_obj[Symbol.for(\"write\")](output);" << '\n' << indent() << "output.writeMessageEnd();" << '\n' + << indent() << "output.flush();" << '\n'; indent_down(); if (gen_es6_) { - indent(f_service_) << "}).catch(err => {" << endl; + indent(f_service_) << "}).catch(err => {" << '\n'; } else { - indent(f_service_) << "}).catch(function (err) {" << endl; + indent(f_service_) << "}).catch(function (err) {" << '\n'; } indent_up(); - indent(f_service_) << js_let_type_ << "result;" << endl; + indent(f_service_) << js_let_type_ << "result;" << '\n'; bool has_exception = false; t_struct* exceptions = tfunction->get_xceptions(); @@ -1550,36 +1606,36 @@ void t_js_generator::generate_process_function(t_service* tservice, t_function* } if (has_exception) { - f_service_ << ") {" << endl; + f_service_ << ") {" << '\n'; indent_up(); - f_service_ << indent() << "result = new " << resultname << "(err);" << endl << indent() + f_service_ << indent() << "result = new " << resultname << "(err);" << '\n' << indent() << "output.writeMessageBegin(\"" << tfunction->get_name() - << "\", Thrift.MessageType.REPLY, seqid);" << endl; + << "\", Thrift.MessageType.REPLY, seqid);" << '\n'; indent_down(); - indent(f_service_) << "} else {" << endl; + indent(f_service_) << "} else {" << '\n'; indent_up(); } f_service_ << indent() << "result = new " "Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN," - " err.message);" << endl << indent() << "output.writeMessageBegin(\"" - << tfunction->get_name() << "\", Thrift.MessageType.EXCEPTION, seqid);" << endl; + " err.message);" << '\n' << indent() << "output.writeMessageBegin(\"" + << tfunction->get_name() << "\", Thrift.MessageType.EXCEPTION, seqid);" << '\n'; if (has_exception) { indent_down(); - indent(f_service_) << "}" << endl; + indent(f_service_) << "}" << '\n'; } - f_service_ << indent() << "result.write(output);" << endl << indent() - << "output.writeMessageEnd();" << endl << indent() << "output.flush();" << endl; + f_service_ << indent() << "result[Symbol.for(\"write\")](output);" << '\n' << indent() + << "output.writeMessageEnd();" << '\n' << indent() << "output.flush();" << '\n'; indent_down(); - indent(f_service_) << "});" << endl; + indent(f_service_) << "});" << '\n'; indent_down(); // End promise style invocation // Callback style invocation - indent(f_service_) << "} else {" << endl; + indent(f_service_) << "} else {" << '\n'; indent_up(); indent(f_service_) << "this._handler." << tfunction->get_name() << "("; @@ -1588,12 +1644,12 @@ void t_js_generator::generate_process_function(t_service* tservice, t_function* } if (gen_es6_) { - f_service_ << "(err, result) => {" << endl; + f_service_ << "(err, result) => {" << '\n'; } else { - f_service_ << "function (err, result) {" << endl; + f_service_ << "function (err, result) {" << '\n'; } indent_up(); - indent(f_service_) << js_let_type_ << "result_obj;" << endl; + indent(f_service_) << js_let_type_ << "result_obj;" << '\n'; indent(f_service_) << "if ((err === null || typeof err === 'undefined')"; if (has_exception) { @@ -1605,35 +1661,35 @@ void t_js_generator::generate_process_function(t_service* tservice, t_function* } } } - f_service_ << ") {" << endl; + f_service_ << ") {" << '\n'; indent_up(); f_service_ << indent() << "result_obj = new " << resultname - << "((err !== null || typeof err === 'undefined') ? err : {success: result});" << endl << indent() + << "((err !== null || typeof err === 'undefined') ? err : {success: result});" << '\n' << indent() << "output.writeMessageBegin(\"" << tfunction->get_name() - << "\", Thrift.MessageType.REPLY, seqid);" << endl; + << "\", Thrift.MessageType.REPLY, seqid);" << '\n'; indent_down(); - indent(f_service_) << "} else {" << endl; + indent(f_service_) << "} else {" << '\n'; indent_up(); f_service_ << indent() << "result_obj = new " "Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN," - " err.message);" << endl << indent() << "output.writeMessageBegin(\"" - << tfunction->get_name() << "\", Thrift.MessageType.EXCEPTION, seqid);" << endl; + " err.message);" << '\n' << indent() << "output.writeMessageBegin(\"" + << tfunction->get_name() << "\", Thrift.MessageType.EXCEPTION, seqid);" << '\n'; indent_down(); - f_service_ << indent() << "}" << endl << indent() << "result_obj.write(output);" << endl << indent() - << "output.writeMessageEnd();" << endl << indent() << "output.flush();" << endl; + f_service_ << indent() << "}" << '\n' << indent() << "result_obj[Symbol.for(\"write\")](output);" << '\n' << indent() + << "output.writeMessageEnd();" << '\n' << indent() << "output.flush();" << '\n'; indent_down(); - indent(f_service_) << "});" << endl; + indent(f_service_) << "});" << '\n'; indent_down(); - indent(f_service_) << "}" << endl; + indent(f_service_) << "}" << '\n'; // End callback style invocation indent_down(); if (gen_es6_) { - indent(f_service_) << "}" << endl; + indent(f_service_) << "}" << '\n'; } else { - indent(f_service_) << "};" << endl; + indent(f_service_) << "};" << '\n'; } } @@ -1650,7 +1706,7 @@ void t_js_generator::generate_service_helpers(t_service* tservice) { vector functions = tservice->get_functions(); vector::iterator f_iter; - f_service_ << "//HELPER FUNCTIONS AND STRUCTURES" << endl << endl; + f_service_ << "//HELPER FUNCTIONS AND STRUCTURES" << '\n' << '\n'; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { t_struct* ts = (*f_iter)->get_arglist(); @@ -1711,27 +1767,27 @@ void t_js_generator::generate_service_client(t_service* tservice) { bool is_subclass_service = tservice->get_extends() != nullptr; + string client_var = js_namespace(tservice->get_program()) + service_name_ + "Client"; if (gen_node_) { - string prefix = has_js_namespace(tservice->get_program()) ? js_namespace(tservice->get_program()) : js_const_type_; - f_service_ << prefix << service_name_ << "Client = " << "exports.Client"; + string prefix = has_js_namespace(tservice->get_program()) ? "" : js_const_type_; + f_service_ << prefix << client_var; if (gen_ts_) { f_service_ts_ << ts_print_doc(tservice) << ts_indent() << ts_declare() << "class " << "Client "; if (tservice->get_extends() != nullptr) { f_service_ts_ << "extends " << tservice->get_extends()->get_name() << ".Client "; } - f_service_ts_ << "{" << endl; + f_service_ts_ << "{" << '\n'; } } else { - f_service_ << js_namespace(tservice->get_program()) << service_name_ - << "Client"; + f_service_ << client_var; if (gen_ts_) { f_service_ts_ << ts_print_doc(tservice) << ts_indent() << ts_declare() << "class " << service_name_ << "Client "; if (is_subclass_service) { f_service_ts_ << "extends " << tservice->get_extends()->get_name() << "Client "; } - f_service_ts_ << "{" << endl; + f_service_ts_ << "{" << '\n'; } } @@ -1740,21 +1796,21 @@ void t_js_generator::generate_service_client(t_service* tservice) { if (is_subclass_service) { f_service_ << " = class " << service_name_ << "Client extends " << js_namespace(tservice->get_extends()->get_program()) - << tservice->get_extends()->get_name() << "Client {" << endl; + << tservice->get_extends()->get_name() << "Client {" << '\n'; } else { - f_service_ << " = class " << service_name_ << "Client {" << endl; + f_service_ << " = class " << service_name_ << "Client {" << '\n'; } indent_up(); if (gen_node_) { - indent(f_service_) << "constructor(output, pClass) {" << endl; + indent(f_service_) << "constructor(output, pClass) {" << '\n'; } else { - indent(f_service_) << "constructor(input, output) {" << endl; + indent(f_service_) << "constructor(input, output) {" << '\n'; } } else { if (gen_node_) { - f_service_ << " = function(output, pClass) {" << endl; + f_service_ << " = function(output, pClass) {" << '\n'; } else { - f_service_ << " = function(input, output) {" << endl; + f_service_ << " = function(input, output) {" << '\n'; } } @@ -1762,65 +1818,65 @@ void t_js_generator::generate_service_client(t_service* tservice) { if (gen_node_) { if (gen_es6_ && is_subclass_service) { - indent(f_service_) << "super(output, pClass);" << endl; + indent(f_service_) << "super(output, pClass);" << '\n'; } - indent(f_service_) << "this.output = output;" << endl; - indent(f_service_) << "this.pClass = pClass;" << endl; - indent(f_service_) << "this._seqid = 0;" << endl; - indent(f_service_) << "this._reqs = {};" << endl; + indent(f_service_) << "this.output = output;" << '\n'; + indent(f_service_) << "this.pClass = pClass;" << '\n'; + indent(f_service_) << "this._seqid = 0;" << '\n'; + indent(f_service_) << "this._reqs = {};" << '\n'; if (gen_ts_) { if(!is_subclass_service) { - f_service_ts_ << ts_indent() << "private output: thrift.TTransport;" << endl - << ts_indent() << "private pClass: thrift.TProtocol;" << endl - << ts_indent() << "private _seqid: number;" << endl - << endl; + f_service_ts_ << ts_indent() << "private output: thrift.TTransport;" << '\n' + << ts_indent() << "private pClass: thrift.TProtocol;" << '\n' + << ts_indent() << "private _seqid: number;" << '\n' + << '\n'; } f_service_ts_ << ts_indent() << "constructor(output: thrift.TTransport, pClass: { new(trans: thrift.TTransport): thrift.TProtocol });" - << endl; + << '\n'; } } else { - indent(f_service_) << "this.input = input;" << endl; - indent(f_service_) << "this.output = (!output) ? input : output;" << endl; - indent(f_service_) << "this.seqid = 0;" << endl; + indent(f_service_) << "this.input = input;" << '\n'; + indent(f_service_) << "this.output = (!output) ? input : output;" << '\n'; + indent(f_service_) << "this.seqid = 0;" << '\n'; if (gen_ts_) { - f_service_ts_ << ts_indent() << "input: Thrift.TJSONProtocol;" << endl << ts_indent() - << "output: Thrift.TJSONProtocol;" << endl << ts_indent() << "seqid: number;" - << endl << endl << ts_indent() + f_service_ts_ << ts_indent() << "input: Thrift.TJSONProtocol;" << '\n' << ts_indent() + << "output: Thrift.TJSONProtocol;" << '\n' << ts_indent() << "seqid: number;" + << '\n' << '\n' << ts_indent() << "constructor(input: Thrift.TJSONProtocol, output?: Thrift.TJSONProtocol);" - << endl; + << '\n'; } } indent_down(); if (gen_es6_) { - indent(f_service_) << "}" << endl; + indent(f_service_) << "}" << '\n'; } else { - indent(f_service_) << "};" << endl; + indent(f_service_) << "};" << '\n'; if (is_subclass_service) { indent(f_service_) << "Thrift.inherits(" << js_namespace(tservice->get_program()) << service_name_ << "Client, " << js_namespace(tservice->get_extends()->get_program()) - << tservice->get_extends()->get_name() << "Client);" << endl; + << tservice->get_extends()->get_name() << "Client);" << '\n'; } else { // init prototype indent(f_service_) << js_namespace(tservice->get_program()) << service_name_ - << "Client.prototype = {};" << endl; + << "Client.prototype = {};" << '\n'; } } // utils for multiplexed services if (gen_node_) { if (gen_es6_) { - indent(f_service_) << "seqid () { return this._seqid; }" << endl; - indent(f_service_) << "new_seqid () { return this._seqid += 1; }" << endl; + indent(f_service_) << "seqid () { return this._seqid; }" << '\n'; + indent(f_service_) << "new_seqid () { return this._seqid += 1; }" << '\n'; } else { indent(f_service_) << js_namespace(tservice->get_program()) << service_name_ - << "Client.prototype.seqid = function() { return this._seqid; };" << endl + << "Client.prototype.seqid = function() { return this._seqid; };" << '\n' << js_namespace(tservice->get_program()) << service_name_ << "Client.prototype.new_seqid = function() { return this._seqid += 1; };" - << endl; + << '\n'; } } @@ -1835,144 +1891,144 @@ void t_js_generator::generate_service_client(t_service* tservice) { string arglist = argument_list(arg_struct); // Open function - f_service_ << endl; + f_service_ << '\n'; if (gen_es6_) { - indent(f_service_) << funname << " (" << arglist << ") {" << endl; + indent(f_service_) << funname << " (" << arglist << ") {" << '\n'; } else { indent(f_service_) << js_namespace(tservice->get_program()) << service_name_ << "Client.prototype." - << function_signature(*f_iter, "", !gen_es6_) << " {" << endl; + << function_signature(*f_iter, "", !gen_es6_) << " {" << '\n'; } indent_up(); if (gen_ts_) { // function definition without callback - f_service_ts_ << ts_print_doc(*f_iter) << ts_indent() << ts_function_signature(*f_iter, false) << endl; + f_service_ts_ << ts_print_doc(*f_iter) << ts_indent() << ts_function_signature(*f_iter, false) << '\n'; if (!gen_es6_) { // overload with callback - f_service_ts_ << ts_print_doc(*f_iter) << ts_indent() << ts_function_signature(*f_iter, true) << endl; + f_service_ts_ << ts_print_doc(*f_iter) << ts_indent() << ts_function_signature(*f_iter, true) << '\n'; } else { // overload with callback - f_service_ts_ << ts_print_doc(*f_iter) << ts_indent() << ts_function_signature(*f_iter, true) << endl; + f_service_ts_ << ts_print_doc(*f_iter) << ts_indent() << ts_function_signature(*f_iter, true) << '\n'; } } if (gen_es6_ && gen_node_) { - indent(f_service_) << "this._seqid = this.new_seqid();" << endl; - indent(f_service_) << js_const_type_ << "self = this;" << endl << indent() - << "return new Promise((resolve, reject) => {" << endl; + indent(f_service_) << "this._seqid = this.new_seqid();" << '\n'; + indent(f_service_) << js_const_type_ << "self = this;" << '\n' << indent() + << "return new Promise((resolve, reject) => {" << '\n'; indent_up(); - indent(f_service_) << "self._reqs[self.seqid()] = (error, result) => {" << endl; + indent(f_service_) << "self._reqs[self.seqid()] = (error, result) => {" << '\n'; indent_up(); - indent(f_service_) << "return error ? reject(error) : resolve(result);" << endl; + indent(f_service_) << "return error ? reject(error) : resolve(result);" << '\n'; indent_down(); - indent(f_service_) << "};" << endl; - indent(f_service_) << "self.send_" << funname << "(" << arglist << ");" << endl; + indent(f_service_) << "};" << '\n'; + indent(f_service_) << "self.send_" << funname << "(" << arglist << ");" << '\n'; indent_down(); - indent(f_service_) << "});" << endl; + indent(f_service_) << "});" << '\n'; } else if (gen_node_) { // Node.js output ./gen-nodejs - f_service_ << indent() << "this._seqid = this.new_seqid();" << endl << indent() - << "if (callback === undefined) {" << endl; + f_service_ << indent() << "this._seqid = this.new_seqid();" << '\n' << indent() + << "if (callback === undefined) {" << '\n'; indent_up(); - f_service_ << indent() << js_const_type_ << "_defer = Q.defer();" << endl << indent() - << "this._reqs[this.seqid()] = function(error, result) {" << endl; + f_service_ << indent() << js_const_type_ << "_defer = Q.defer();" << '\n' << indent() + << "this._reqs[this.seqid()] = function(error, result) {" << '\n'; indent_up(); - indent(f_service_) << "if (error) {" << endl; + indent(f_service_) << "if (error) {" << '\n'; indent_up(); - indent(f_service_) << "_defer.reject(error);" << endl; + indent(f_service_) << "_defer.reject(error);" << '\n'; indent_down(); - indent(f_service_) << "} else {" << endl; + indent(f_service_) << "} else {" << '\n'; indent_up(); - indent(f_service_) << "_defer.resolve(result);" << endl; + indent(f_service_) << "_defer.resolve(result);" << '\n'; indent_down(); - indent(f_service_) << "}" << endl; + indent(f_service_) << "}" << '\n'; indent_down(); - indent(f_service_) << "};" << endl; - f_service_ << indent() << "this.send_" << funname << "(" << arglist << ");" << endl - << indent() << "return _defer.promise;" << endl; + indent(f_service_) << "};" << '\n'; + f_service_ << indent() << "this.send_" << funname << "(" << arglist << ");" << '\n' + << indent() << "return _defer.promise;" << '\n'; indent_down(); - indent(f_service_) << "} else {" << endl; + indent(f_service_) << "} else {" << '\n'; indent_up(); - f_service_ << indent() << "this._reqs[this.seqid()] = callback;" << endl << indent() - << "this.send_" << funname << "(" << arglist << ");" << endl; + f_service_ << indent() << "this._reqs[this.seqid()] = callback;" << '\n' << indent() + << "this.send_" << funname << "(" << arglist << ");" << '\n'; indent_down(); - indent(f_service_) << "}" << endl; + indent(f_service_) << "}" << '\n'; } else if (gen_es6_) { - f_service_ << indent() << js_const_type_ << "self = this;" << endl << indent() - << "return new Promise((resolve, reject) => {" << endl; + f_service_ << indent() << js_const_type_ << "self = this;" << '\n' << indent() + << "return new Promise((resolve, reject) => {" << '\n'; indent_up(); f_service_ << indent() << "self.send_" << funname << "(" << arglist - << (arglist.empty() ? "" : ", ") << "(error, result) => {" << endl; + << (arglist.empty() ? "" : ", ") << "(error, result) => {" << '\n'; indent_up(); - indent(f_service_) << "return error ? reject(error) : resolve(result);" << endl; + indent(f_service_) << "return error ? reject(error) : resolve(result);" << '\n'; indent_down(); - f_service_ << indent() << "});" << endl; + f_service_ << indent() << "});" << '\n'; indent_down(); - f_service_ << indent() << "});" << endl; + f_service_ << indent() << "});" << '\n'; } else if (gen_jquery_) { // jQuery output ./gen-js - f_service_ << indent() << "if (callback === undefined) {" << endl; + f_service_ << indent() << "if (callback === undefined) {" << '\n'; indent_up(); - f_service_ << indent() << "this.send_" << funname << "(" << arglist << ");" << endl; + f_service_ << indent() << "this.send_" << funname << "(" << arglist << ");" << '\n'; if (!(*f_iter)->is_oneway()) { f_service_ << indent(); if (!(*f_iter)->get_returntype()->is_void()) { f_service_ << "return "; } - f_service_ << "this.recv_" << funname << "();" << endl; + f_service_ << "this.recv_" << funname << "();" << '\n'; } indent_down(); - f_service_ << indent() << "} else {" << endl; + f_service_ << indent() << "} else {" << '\n'; indent_up(); f_service_ << indent() << js_const_type_ << "postData = this.send_" << funname << "(" << arglist - << (arglist.empty() ? "" : ", ") << "true);" << endl; - f_service_ << indent() << "return this.output.getTransport()" << endl; + << (arglist.empty() ? "" : ", ") << "true);" << '\n'; + f_service_ << indent() << "return this.output.getTransport()" << '\n'; indent_up(); f_service_ << indent() << ".jqRequest(this, postData, arguments, this.recv_" << funname - << ");" << endl; + << ");" << '\n'; indent_down(); indent_down(); - f_service_ << indent() << "}" << endl; + f_service_ << indent() << "}" << '\n'; } else { // Standard JavaScript ./gen-js f_service_ << indent() << "this.send_" << funname << "(" << arglist - << (arglist.empty() ? "" : ", ") << "callback); " << endl; + << (arglist.empty() ? "" : ", ") << "callback); " << '\n'; if (!(*f_iter)->is_oneway()) { - f_service_ << indent() << "if (!callback) {" << endl; + f_service_ << indent() << "if (!callback) {" << '\n'; f_service_ << indent(); if (!(*f_iter)->get_returntype()->is_void()) { f_service_ << " return "; } - f_service_ << "this.recv_" << funname << "();" << endl; - f_service_ << indent() << "}" << endl; + f_service_ << "this.recv_" << funname << "();" << '\n'; + f_service_ << indent() << "}" << '\n'; } } indent_down(); if (gen_es6_) { - indent(f_service_) << "}" << endl << endl; + indent(f_service_) << "}" << '\n' << '\n'; } else { - indent(f_service_) << "};" << endl << endl; + indent(f_service_) << "};" << '\n' << '\n'; } // Send function if (gen_es6_) { if (gen_node_) { - indent(f_service_) << "send_" << funname << " (" << arglist << ") {" << endl; + indent(f_service_) << "send_" << funname << " (" << arglist << ") {" << '\n'; } else { // ES6 js still uses callbacks here. Should refactor this to promise style later.. - indent(f_service_) << "send_" << funname << " (" << argument_list(arg_struct, true) << ") {" << endl; + indent(f_service_) << "send_" << funname << " (" << argument_list(arg_struct, true) << ") {" << '\n'; } } else { indent(f_service_) << js_namespace(tservice->get_program()) << service_name_ << "Client.prototype.send_" - << function_signature(*f_iter, "", !gen_node_) << " {" << endl; + << function_signature(*f_iter, "", !gen_node_) << " {" << '\n'; } indent_up(); std::string outputVar; if (gen_node_) { - f_service_ << indent() << js_const_type_ << "output = new this.pClass(this.output);" << endl; + f_service_ << indent() << js_const_type_ << "output = new this.pClass(this.output);" << '\n'; outputVar = "output"; } else { outputVar = "this.output"; @@ -1988,127 +2044,127 @@ void t_js_generator::generate_service_client(t_service* tservice) { // It is possible that a method argument is named "params", we need to ensure the locally // generated identifier "params" is uniquely named std::string params_identifier = this->next_identifier_name(fields, "params"); - f_service_ << indent() << js_const_type_ << params_identifier << " = {" << endl; + f_service_ << indent() << js_const_type_ << params_identifier << " = {" << '\n'; indent_up(); for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) { indent(f_service_) << (*fld_iter)->get_name() << ": " << (*fld_iter)->get_name(); if (fld_iter != fields.end()-1) { - f_service_ << "," << endl; + f_service_ << "," << '\n'; } else { - f_service_ << endl; + f_service_ << '\n'; } } indent_down(); - indent(f_service_) << "};" << endl; + indent(f_service_) << "};" << '\n'; // NOTE: "args" is a reserved keyword, so no need to generate a unique identifier - indent(f_service_) << js_const_type_ << "args = new " << argsname << "(" << params_identifier << ");" << endl; + indent(f_service_) << js_const_type_ << "args = new " << argsname << "(" << params_identifier << ");" << '\n'; } else { - indent(f_service_) << js_const_type_ << "args = new " << argsname << "();" << endl; + indent(f_service_) << js_const_type_ << "args = new " << argsname << "();" << '\n'; } // Serialize the request header within try/catch - indent(f_service_) << "try {" << endl; + indent(f_service_) << "try {" << '\n'; indent_up(); if (gen_node_) { f_service_ << indent() << outputVar << ".writeMessageBegin('" << (*f_iter)->get_name() - << "', " << messageType << ", this.seqid());" << endl; + << "', " << messageType << ", this.seqid());" << '\n'; } else { f_service_ << indent() << outputVar << ".writeMessageBegin('" << (*f_iter)->get_name() - << "', " << messageType << ", this.seqid);" << endl; + << "', " << messageType << ", this.seqid);" << '\n'; } // Write to the stream - f_service_ << indent() << "args.write(" << outputVar << ");" << endl << indent() << outputVar - << ".writeMessageEnd();" << endl; + f_service_ << indent() << "args[Symbol.for(\"write\")](" << outputVar << ");" << '\n' << indent() << outputVar + << ".writeMessageEnd();" << '\n'; if (gen_node_) { if((*f_iter)->is_oneway()) { - f_service_ << indent() << "this.output.flush();" << endl; - f_service_ << indent() << js_const_type_ << "callback = this._reqs[this.seqid()] || function() {};" << endl; - f_service_ << indent() << "delete this._reqs[this.seqid()];" << endl; - f_service_ << indent() << "callback(null);" << endl; + f_service_ << indent() << "this.output.flush();" << '\n'; + f_service_ << indent() << js_const_type_ << "callback = this._reqs[this.seqid()] || function() {};" << '\n'; + f_service_ << indent() << "delete this._reqs[this.seqid()];" << '\n'; + f_service_ << indent() << "callback(null);" << '\n'; } else { - f_service_ << indent() << "return this.output.flush();" << endl; + f_service_ << indent() << "return this.output.flush();" << '\n'; } } else { if (gen_jquery_) { - f_service_ << indent() << "return this.output.getTransport().flush(callback);" << endl; + f_service_ << indent() << "return this.output.getTransport().flush(callback);" << '\n'; } else if (gen_es6_) { - f_service_ << indent() << js_const_type_ << "self = this;" << endl; + f_service_ << indent() << js_const_type_ << "self = this;" << '\n'; if((*f_iter)->is_oneway()) { - f_service_ << indent() << "this.output.getTransport().flush(true, null);" << endl; - f_service_ << indent() << "callback();" << endl; + f_service_ << indent() << "this.output.getTransport().flush(true, null);" << '\n'; + f_service_ << indent() << "callback();" << '\n'; } else { - f_service_ << indent() << "this.output.getTransport().flush(true, () => {" << endl; + f_service_ << indent() << "this.output.getTransport().flush(true, () => {" << '\n'; indent_up(); - f_service_ << indent() << js_let_type_ << "error = null, result = null;" << endl; - f_service_ << indent() << "try {" << endl; - f_service_ << indent() << " result = self.recv_" << funname << "();" << endl; - f_service_ << indent() << "} catch (e) {" << endl; - f_service_ << indent() << " error = e;" << endl; - f_service_ << indent() << "}" << endl; - f_service_ << indent() << "callback(error, result);" << endl; + f_service_ << indent() << js_let_type_ << "error = null, result = null;" << '\n'; + f_service_ << indent() << "try {" << '\n'; + f_service_ << indent() << " result = self.recv_" << funname << "();" << '\n'; + f_service_ << indent() << "} catch (e) {" << '\n'; + f_service_ << indent() << " error = e;" << '\n'; + f_service_ << indent() << "}" << '\n'; + f_service_ << indent() << "callback(error, result);" << '\n'; indent_down(); - f_service_ << indent() << "});" << endl; + f_service_ << indent() << "});" << '\n'; } } else { - f_service_ << indent() << "if (callback) {" << endl; + f_service_ << indent() << "if (callback) {" << '\n'; indent_up(); if((*f_iter)->is_oneway()) { - f_service_ << indent() << "this.output.getTransport().flush(true, null);" << endl; - f_service_ << indent() << "callback();" << endl; + f_service_ << indent() << "this.output.getTransport().flush(true, null);" << '\n'; + f_service_ << indent() << "callback();" << '\n'; } else { - f_service_ << indent() << js_const_type_ << "self = this;" << endl; - f_service_ << indent() << "this.output.getTransport().flush(true, function() {" << endl; + f_service_ << indent() << js_const_type_ << "self = this;" << '\n'; + f_service_ << indent() << "this.output.getTransport().flush(true, function() {" << '\n'; indent_up(); - f_service_ << indent() << js_let_type_ << "result = null;" << endl; - f_service_ << indent() << "try {" << endl; - f_service_ << indent() << " result = self.recv_" << funname << "();" << endl; - f_service_ << indent() << "} catch (e) {" << endl; - f_service_ << indent() << " result = e;" << endl; - f_service_ << indent() << "}" << endl; - f_service_ << indent() << "callback(result);" << endl; + f_service_ << indent() << js_let_type_ << "result = null;" << '\n'; + f_service_ << indent() << "try {" << '\n'; + f_service_ << indent() << " result = self.recv_" << funname << "();" << '\n'; + f_service_ << indent() << "} catch (e) {" << '\n'; + f_service_ << indent() << " result = e;" << '\n'; + f_service_ << indent() << "}" << '\n'; + f_service_ << indent() << "callback(result);" << '\n'; indent_down(); - f_service_ << indent() << "});" << endl; + f_service_ << indent() << "});" << '\n'; } indent_down(); - f_service_ << indent() << "} else {" << endl; - f_service_ << indent() << " return this.output.getTransport().flush();" << endl; - f_service_ << indent() << "}" << endl; + f_service_ << indent() << "} else {" << '\n'; + f_service_ << indent() << " return this.output.getTransport().flush();" << '\n'; + f_service_ << indent() << "}" << '\n'; } } indent_down(); - f_service_ << indent() << "}" << endl; + f_service_ << indent() << "}" << '\n'; // Reset the transport and delete registered callback if there was a serialization error - f_service_ << indent() << "catch (e) {" << endl; + f_service_ << indent() << "catch (e) {" << '\n'; indent_up(); if (gen_node_) { - f_service_ << indent() << "delete this._reqs[this.seqid()];" << endl; - f_service_ << indent() << "if (typeof " << outputVar << ".reset === 'function') {" << endl; - f_service_ << indent() << " " << outputVar << ".reset();" << endl; - f_service_ << indent() << "}" << endl; + f_service_ << indent() << "delete this._reqs[this.seqid()];" << '\n'; + f_service_ << indent() << "if (typeof " << outputVar << ".reset === 'function') {" << '\n'; + f_service_ << indent() << " " << outputVar << ".reset();" << '\n'; + f_service_ << indent() << "}" << '\n'; } else { - f_service_ << indent() << "if (typeof " << outputVar << ".getTransport().reset === 'function') {" << endl; - f_service_ << indent() << " " << outputVar << ".getTransport().reset();" << endl; - f_service_ << indent() << "}" << endl; + f_service_ << indent() << "if (typeof " << outputVar << ".getTransport().reset === 'function') {" << '\n'; + f_service_ << indent() << " " << outputVar << ".getTransport().reset();" << '\n'; + f_service_ << indent() << "}" << '\n'; } - f_service_ << indent() << "throw e;" << endl; + f_service_ << indent() << "throw e;" << '\n'; indent_down(); - f_service_ << indent() << "}" << endl; + f_service_ << indent() << "}" << '\n'; indent_down(); // Close send function if (gen_es6_) { - indent(f_service_) << "}" << endl; + indent(f_service_) << "}" << '\n'; } else { - indent(f_service_) << "};" << endl; + indent(f_service_) << "};" << '\n'; } // Receive function @@ -2116,19 +2172,19 @@ void t_js_generator::generate_service_client(t_service* tservice) { std::string resultname = js_namespace(tservice->get_program()) + service_name_ + "_" + (*f_iter)->get_name() + "_result"; - f_service_ << endl; + f_service_ << '\n'; // Open receive function if (gen_node_) { if (gen_es6_) { - indent(f_service_) << "recv_" << (*f_iter)->get_name() << " (input, mtype, rseqid) {" << endl; + indent(f_service_) << "recv_" << (*f_iter)->get_name() << " (input, mtype, rseqid) {" << '\n'; } else { indent(f_service_) << js_namespace(tservice->get_program()) << service_name_ << "Client.prototype.recv_" << (*f_iter)->get_name() - << " = function(input,mtype,rseqid) {" << endl; + << " = function(input,mtype,rseqid) {" << '\n'; } } else { if (gen_es6_) { - indent(f_service_) << "recv_" << (*f_iter)->get_name() << " () {" << endl; + indent(f_service_) << "recv_" << (*f_iter)->get_name() << " () {" << '\n'; } else { t_struct noargs(program_); @@ -2136,7 +2192,7 @@ void t_js_generator::generate_service_client(t_service* tservice) { string("recv_") + (*f_iter)->get_name(), &noargs); indent(f_service_) << js_namespace(tservice->get_program()) << service_name_ - << "Client.prototype." << function_signature(&recv_function) << " {" << endl; + << "Client.prototype." << function_signature(&recv_function) << " {" << '\n'; } } @@ -2150,68 +2206,74 @@ void t_js_generator::generate_service_client(t_service* tservice) { } if (gen_node_) { - f_service_ << indent() << js_const_type_ << "callback = this._reqs[rseqid] || function() {};" << endl - << indent() << "delete this._reqs[rseqid];" << endl; + f_service_ << indent() << js_const_type_ << "callback = this._reqs[rseqid] || function() {};" << '\n' + << indent() << "delete this._reqs[rseqid];" << '\n'; } else { - f_service_ << indent() << js_const_type_ << "ret = this.input.readMessageBegin();" << endl - << indent() << js_const_type_ << "mtype = ret.mtype;" << endl; + f_service_ << indent() << js_const_type_ << "ret = this.input.readMessageBegin();" << '\n' + << indent() << js_const_type_ << "mtype = ret.mtype;" << '\n'; } - f_service_ << indent() << "if (mtype == Thrift.MessageType.EXCEPTION) {" << endl; + f_service_ << indent() << "if (mtype == Thrift.MessageType.EXCEPTION) {" << '\n'; indent_up(); - f_service_ << indent() << js_const_type_ << "x = new Thrift.TApplicationException();" << endl - << indent() << "x.read(" << inputVar << ");" << endl - << indent() << inputVar << ".readMessageEnd();" << endl - << indent() << render_recv_throw("x") << endl; + f_service_ << indent() << js_const_type_ << "x = new Thrift.TApplicationException();" << '\n' + << indent() << "x[Symbol.for(\"read\")](" << inputVar << ");" << '\n' + << indent() << inputVar << ".readMessageEnd();" << '\n' + << indent() << render_recv_throw("x") << '\n'; scope_down(f_service_); - f_service_ << indent() << js_const_type_ << "result = new " << resultname << "();" << endl << indent() - << "result.read(" << inputVar << ");" << endl; + f_service_ << indent() << js_const_type_ << "result = new " << resultname << "();" << '\n' << indent() + << "result[Symbol.for(\"read\")](" << inputVar << ");" << '\n'; - f_service_ << indent() << inputVar << ".readMessageEnd();" << endl << endl; + f_service_ << indent() << inputVar << ".readMessageEnd();" << '\n' << '\n'; t_struct* xs = (*f_iter)->get_xceptions(); const std::vector& xceptions = xs->get_members(); vector::const_iterator x_iter; for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { - f_service_ << indent() << "if (null !== result." << (*x_iter)->get_name() << ") {" << endl + f_service_ << indent() << "if (null !== result." << (*x_iter)->get_name() << ") {" << '\n' << indent() << " " << render_recv_throw("result." + (*x_iter)->get_name()) - << endl << indent() << "}" << endl; + << '\n' << indent() << "}" << '\n'; } // Careful, only return result if not a void function if (!(*f_iter)->get_returntype()->is_void()) { - f_service_ << indent() << "if (null !== result.success) {" << endl << indent() << " " - << render_recv_return("result.success") << endl << indent() << "}" << endl; + f_service_ << indent() << "if (null !== result.success) {" << '\n' << indent() << " " + << render_recv_return("result.success") << '\n' << indent() << "}" << '\n'; f_service_ << indent() << render_recv_throw("'" + (*f_iter)->get_name() + " failed: unknown result'") - << endl; + << '\n'; } else { if (gen_node_) { - indent(f_service_) << "callback(null);" << endl; + indent(f_service_) << "callback(null);" << '\n'; } else { - indent(f_service_) << "return;" << endl; + indent(f_service_) << "return;" << '\n'; } } // Close receive function indent_down(); if (gen_es6_) { - indent(f_service_) << "}" << endl; + indent(f_service_) << "}" << '\n'; } else { - indent(f_service_) << "};" << endl; + indent(f_service_) << "};" << '\n'; } } } // Finish class definitions if (gen_ts_) { - f_service_ts_ << ts_indent() << "}" << endl; + f_service_ts_ << ts_indent() << "}" << '\n'; } if (gen_es6_) { indent_down(); - f_service_ << "};" << endl; + f_service_ << "};" << '\n'; + } + + if(gen_esm_) { + f_service_ << "export { " << client_var << " as Client };" << '\n'; + } else if(gen_node_) { + f_service_ << "exports.Client = " << client_var << ";" << '\n'; } } @@ -2292,7 +2354,7 @@ void t_js_generator::generate_deserialize_field(ostream& out, out << ".value"; } - out << ";" << endl; + out << ";" << '\n'; } else { printf("DO NOT KNOW HOW TO DESERIALIZE FIELD '%s' TYPE '%s'\n", tfield->get_name().c_str(), @@ -2308,7 +2370,7 @@ void t_js_generator::generate_deserialize_field(ostream& out, */ void t_js_generator::generate_deserialize_struct(ostream& out, t_struct* tstruct, string prefix) { out << indent() << prefix << " = new " << js_type_namespace(tstruct->get_program()) - << tstruct->get_name() << "();" << endl << indent() << prefix << ".read(input);" << endl; + << tstruct->get_name() << "();" << '\n' << indent() << prefix << "[Symbol.for(\"read\")](input);" << '\n'; } void t_js_generator::generate_deserialize_container(ostream& out, t_type* ttype, string prefix) { @@ -2319,36 +2381,36 @@ void t_js_generator::generate_deserialize_container(ostream& out, t_type* ttype, // Declare variables, read header if (ttype->is_map()) { - out << indent() << prefix << " = new Map();" << endl; + out << indent() << prefix << " = {};" << '\n'; - out << indent() << js_const_type_ << rtmp3 << " = input.readMapBegin();" << endl; - out << indent() << js_const_type_ << size << " = " << rtmp3 << ".size || 0;" << endl; + out << indent() << js_const_type_ << rtmp3 << " = input.readMapBegin();" << '\n'; + out << indent() << js_const_type_ << size << " = " << rtmp3 << ".size || 0;" << '\n'; } else if (ttype->is_set()) { - out << indent() << prefix << " = [];" << endl - << indent() << js_const_type_ << rtmp3 << " = input.readSetBegin();" << endl - << indent() << js_const_type_ << size << " = " << rtmp3 << ".size || 0;" << endl; + out << indent() << prefix << " = [];" << '\n' + << indent() << js_const_type_ << rtmp3 << " = input.readSetBegin();" << '\n' + << indent() << js_const_type_ << size << " = " << rtmp3 << ".size || 0;" << '\n'; } else if (ttype->is_list()) { - out << indent() << prefix << " = [];" << endl - << indent() << js_const_type_ << rtmp3 << " = input.readListBegin();" << endl - << indent() << js_const_type_ << size << " = " << rtmp3 << ".size || 0;" << endl; + out << indent() << prefix << " = [];" << '\n' + << indent() << js_const_type_ << rtmp3 << " = input.readListBegin();" << '\n' + << indent() << js_const_type_ << size << " = " << rtmp3 << ".size || 0;" << '\n'; } // For loop iterates over elements string i = tmp("_i"); - indent(out) << "for (" << js_let_type_ << i << " = 0; " << i << " < " << size << "; ++" << i << ") {" << endl; + indent(out) << "for (" << js_let_type_ << i << " = 0; " << i << " < " << size << "; ++" << i << ") {" << '\n'; indent_up(); if (ttype->is_map()) { if (!gen_node_) { - out << indent() << "if (" << i << " > 0 ) {" << endl << indent() - << " if (input.rstack.length > input.rpos[input.rpos.length -1] + 1) {" << endl - << indent() << " input.rstack.pop();" << endl << indent() << " }" << endl << indent() - << "}" << endl; + out << indent() << "if (" << i << " > 0 ) {" << '\n' << indent() + << " if (input.rstack.length > input.rpos[input.rpos.length -1] + 1) {" << '\n' + << indent() << " input.rstack.pop();" << '\n' << indent() << " }" << '\n' << indent() + << "}" << '\n'; } generate_deserialize_map_element(out, (t_map*)ttype, prefix); @@ -2362,11 +2424,11 @@ void t_js_generator::generate_deserialize_container(ostream& out, t_type* ttype, // Read container end if (ttype->is_map()) { - indent(out) << "input.readMapEnd();" << endl; + indent(out) << "input.readMapEnd();" << '\n'; } else if (ttype->is_set()) { - indent(out) << "input.readSetEnd();" << endl; + indent(out) << "input.readSetEnd();" << '\n'; } else if (ttype->is_list()) { - indent(out) << "input.readListEnd();" << endl; + indent(out) << "input.readListEnd();" << '\n'; } } @@ -2379,23 +2441,24 @@ void t_js_generator::generate_deserialize_map_element(ostream& out, t_map* tmap, t_field fkey(tmap->get_key_type(), key); t_field fval(tmap->get_val_type(), val); - indent(out) << declare_field(&fkey, false, false) << ";" << endl; - indent(out) << declare_field(&fval, false, false) << ";" << endl; + indent(out) << declare_field(&fkey, false, false) << ";" << '\n'; + indent(out) << declare_field(&fval, false, false) << ";" << '\n'; generate_deserialize_field(out, &fkey); generate_deserialize_field(out, &fval); - indent(out) << prefix << ".set(" << key << ", " << val << ");" << endl; + + indent(out) << prefix << "[" << key << "] = " << val << ";" << '\n'; } void t_js_generator::generate_deserialize_set_element(ostream& out, t_set* tset, string prefix) { string elem = tmp("elem"); t_field felem(tset->get_elem_type(), elem); - indent(out) << js_let_type_ << elem << " = null;" << endl; + indent(out) << js_let_type_ << elem << " = null;" << '\n'; generate_deserialize_field(out, &felem); - indent(out) << prefix << ".push(" << elem << ");" << endl; + indent(out) << prefix << ".push(" << elem << ");" << '\n'; } void t_js_generator::generate_deserialize_list_element(ostream& out, @@ -2404,11 +2467,11 @@ void t_js_generator::generate_deserialize_list_element(ostream& out, string elem = tmp("elem"); t_field felem(tlist->get_elem_type(), elem); - indent(out) << js_let_type_ << elem << " = null;" << endl; + indent(out) << js_let_type_ << elem << " = null;" << '\n'; generate_deserialize_field(out, &felem); - indent(out) << prefix << ".push(" << elem << ");" << endl; + indent(out) << prefix << ".push(" << elem << ");" << '\n'; } /** @@ -2472,7 +2535,7 @@ void t_js_generator::generate_serialize_field(ostream& out, t_field* tfield, str } else if (type->is_enum()) { out << "writeI32(" << name << ")"; } - out << ";" << endl; + out << ";" << '\n'; } else { printf("DO NOT KNOW HOW TO SERIALIZE FIELD '%s%s' TYPE '%s'\n", @@ -2490,7 +2553,7 @@ void t_js_generator::generate_serialize_field(ostream& out, t_field* tfield, str */ void t_js_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix) { (void)tstruct; - indent(out) << prefix << ".write(output);" << endl; + indent(out) << prefix << "[Symbol.for(\"write\")](output);" << '\n'; } /** @@ -2500,23 +2563,25 @@ void t_js_generator::generate_serialize_container(ostream& out, t_type* ttype, s if (ttype->is_map()) { indent(out) << "output.writeMapBegin(" << type_to_enum(((t_map*)ttype)->get_key_type()) << ", " << type_to_enum(((t_map*)ttype)->get_val_type()) << ", " - << prefix << ".size);" << endl; + << "Thrift.objectLength(" << prefix << "));" << '\n'; } else if (ttype->is_set()) { indent(out) << "output.writeSetBegin(" << type_to_enum(((t_set*)ttype)->get_elem_type()) << ", " - << prefix << ".length);" << endl; + << prefix << ".length);" << '\n'; } else if (ttype->is_list()) { indent(out) << "output.writeListBegin(" << type_to_enum(((t_list*)ttype)->get_elem_type()) - << ", " << prefix << ".length);" << endl; + << ", " << prefix << ".length);" << '\n'; } if (ttype->is_map()) { string kiter = tmp("kiter"); string viter = tmp("viter"); - string serialize_func = tmp("func"); - indent(out) << js_let_type_ << serialize_func << " = function(" << viter << ", " << kiter << ") {" << endl; + indent(out) << "for (" << js_let_type_ << kiter << " in " << prefix << ") {" << '\n'; + indent_up(); + indent(out) << "if (" << prefix << ".hasOwnProperty(" << kiter << ")) {" << '\n'; indent_up(); + indent(out) << js_let_type_ << viter << " = " << prefix << "[" << kiter << "];" << '\n'; generate_serialize_map_element(out, (t_map*)ttype, kiter, viter); indent_down(); indent(out) << "};" << endl; @@ -2524,33 +2589,33 @@ void t_js_generator::generate_serialize_container(ostream& out, t_type* ttype, s } else if (ttype->is_set()) { string iter = tmp("iter"); - indent(out) << "for (" << js_let_type_ << iter << " in " << prefix << ") {" << endl; + indent(out) << "for (" << js_let_type_ << iter << " in " << prefix << ") {" << '\n'; indent_up(); - indent(out) << "if (" << prefix << ".hasOwnProperty(" << iter << ")) {" << endl; + indent(out) << "if (" << prefix << ".hasOwnProperty(" << iter << ")) {" << '\n'; indent_up(); - indent(out) << iter << " = " << prefix << "[" << iter << "];" << endl; + indent(out) << iter << " = " << prefix << "[" << iter << "];" << '\n'; generate_serialize_set_element(out, (t_set*)ttype, iter); scope_down(out); scope_down(out); } else if (ttype->is_list()) { string iter = tmp("iter"); - indent(out) << "for (" << js_let_type_ << iter << " in " << prefix << ") {" << endl; + indent(out) << "for (" << js_let_type_ << iter << " in " << prefix << ") {" << '\n'; indent_up(); - indent(out) << "if (" << prefix << ".hasOwnProperty(" << iter << ")) {" << endl; + indent(out) << "if (" << prefix << ".hasOwnProperty(" << iter << ")) {" << '\n'; indent_up(); - indent(out) << iter << " = " << prefix << "[" << iter << "];" << endl; + indent(out) << iter << " = " << prefix << "[" << iter << "];" << '\n'; generate_serialize_list_element(out, (t_list*)ttype, iter); scope_down(out); scope_down(out); } if (ttype->is_map()) { - indent(out) << "output.writeMapEnd();" << endl; + indent(out) << "output.writeMapEnd();" << '\n'; } else if (ttype->is_set()) { - indent(out) << "output.writeSetEnd();" << endl; + indent(out) << "output.writeSetEnd();" << '\n'; } else if (ttype->is_list()) { - indent(out) << "output.writeListEnd();" << endl; + indent(out) << "output.writeListEnd();" << '\n'; } } diff --git a/compiler/cpp/src/thrift/generate/t_json_generator.cc b/compiler/cpp/src/thrift/generate/t_json_generator.cc index e91d65ad5db..3fb973a4f37 100644 --- a/compiler/cpp/src/thrift/generate/t_json_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_json_generator.cc @@ -42,8 +42,6 @@ using std::stringstream; using std::vector; using std::stack; -static const string endl = "\n"; -static const string quot = "\""; static const bool NO_INDENT = false; static const bool FORCE_STRING = true; @@ -182,20 +180,20 @@ string t_json_generator::escape_json_string(const string& input) { } void t_json_generator::start_object(bool should_indent) { - f_json_ << (should_indent ? indent() : "") << "{" << endl; + f_json_ << (should_indent ? indent() : "") << "{" << '\n'; indent_up(); comma_needed_.push(false); } void t_json_generator::start_array() { - f_json_ << "[" << endl; + f_json_ << "[" << '\n'; indent_up(); comma_needed_.push(false); } void t_json_generator::write_comma_if_needed() { if (comma_needed_.top()) { - f_json_ << "," << endl; + f_json_ << "," << '\n'; } } @@ -230,14 +228,14 @@ void t_json_generator::write_key_and_bool(string key, bool val) { void t_json_generator::end_object() { indent_down(); - f_json_ << endl << indent() << "}"; + f_json_ << '\n' << indent() << "}"; comma_needed_.pop(); } void t_json_generator::end_array() { indent_down(); if (comma_needed_.top()) { - f_json_ << endl; + f_json_ << '\n'; } indent(f_json_) << "]"; comma_needed_.pop(); @@ -296,7 +294,7 @@ void t_json_generator::write_type_spec(t_type* ttype) { } void t_json_generator::close_generator() { - f_json_ << endl; + f_json_ << '\n'; f_json_.close(); } @@ -471,7 +469,7 @@ void t_json_generator::generate_typedef(t_typedef* ttypedef) { } void t_json_generator::write_string(const string& value) { - f_json_ << quot << escape_json_string(value) << quot; + f_json_ << '\"' << escape_json_string(value) << '\"'; } void t_json_generator::write_const_value(t_const_value* value, bool should_force_string) { @@ -537,7 +535,7 @@ void t_json_generator::write_const_value(t_const_value* value, bool should_force } string t_json_generator::json_str(const string& str) { - return quot + escape_json_string(str) + quot; + return string("\"") + escape_json_string(str) + string("\""); } void t_json_generator::generate_constant(t_const* con) { diff --git a/compiler/cpp/src/thrift/generate/t_kotlin_generator.cc b/compiler/cpp/src/thrift/generate/t_kotlin_generator.cc index 2cf81e8c8a5..40e34d3e608 100644 --- a/compiler/cpp/src/thrift/generate/t_kotlin_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_kotlin_generator.cc @@ -45,8 +45,6 @@ using std::string; using std::stringstream; using std::vector; -static const string endl = "\n"; // avoid ostream << std::endl flushes - static const string KOTLIN_RESERVED_WORDS[] = { "as", "as?", "break", "class", "continue", "do", "else", "false", "for", "fun", "if", "in", "!in", "interface", @@ -211,7 +209,7 @@ void t_kotlin_generator::init_generator() { * Nothing in Kotlin generator */ void t_kotlin_generator::close_generator() { - f_types_ << endl; + f_types_ << '\n'; f_types_.close(); } @@ -224,7 +222,7 @@ void t_kotlin_generator::close_generator() { */ void t_kotlin_generator::generate_typedef(t_typedef* ttypedef) { f_types_ << "typealias " << ttypedef->get_symbolic() << " = " - << type_name(ttypedef->get_type(), true) << endl; + << type_name(ttypedef->get_type(), true) << '\n'; } void t_kotlin_generator::generate_enum(t_enum* tenum) { @@ -243,32 +241,32 @@ void t_kotlin_generator::generate_enum(t_enum* tenum) { auto first = true; auto enum_values = tenum->get_constants(); for (auto& enum_value : enum_values) { - f_enum << (first ? "" : ",") << endl; + f_enum << (first ? "" : ",") << '\n'; first = false; indent(f_enum) << enum_value->get_name() << "(" << enum_value->get_value() << ")"; } if (first) { indent(f_enum); } - f_enum << ";" << endl << endl; - indent(f_enum) << "override fun getValue() = value" << endl << endl; + f_enum << ";" << '\n' << '\n'; + indent(f_enum) << "override fun getValue() = value" << '\n' << '\n'; { - indent(f_enum) << "companion object {" << endl; + indent(f_enum) << "companion object {" << '\n'; indent_up(); { - indent(f_enum) << "@kotlin.jvm.JvmStatic" << endl; + indent(f_enum) << "@kotlin.jvm.JvmStatic" << '\n'; indent(f_enum) << "fun findByValue(i: kotlin.Int): " << kotlin_safe_name(tenum->get_name()) - << "? {" << endl; + << "? {" << '\n'; indent_up(); { - indent(f_enum) << "return when (i) {" << endl; + indent(f_enum) << "return when (i) {" << '\n'; indent_up(); { auto enum_values = tenum->get_constants(); for (auto& enum_value : enum_values) { - indent(f_enum) << enum_value->get_value() << " -> " << enum_value->get_name() << endl; + indent(f_enum) << enum_value->get_value() << " -> " << enum_value->get_name() << '\n'; } - indent(f_enum) << "else -> null" << endl; + indent(f_enum) << "else -> null" << '\n'; } scope_down(f_enum); } @@ -324,7 +322,7 @@ void t_kotlin_generator::generate_consts(std::vector consts) { } else { // TODO } - f_types_ << endl; + f_types_ << '\n'; } } @@ -444,7 +442,7 @@ void t_kotlin_generator::generate_struct_field_name_constants(std::ostream& out, t_struct* tstruct) { indent(out) << "enum class _Fields(private val thriftFieldId: kotlin.Short, private val " "fieldName: kotlin.String) : org.apache.thrift.TFieldIdEnum {" - << endl; + << '\n'; indent_up(); { // fields @@ -452,7 +450,7 @@ void t_kotlin_generator::generate_struct_field_name_constants(std::ostream& out, bool first = true; for (auto& field : tstruct->get_members()) { if (!first) { - out << "," << endl; + out << "," << '\n'; } first = false; indent(out) << constant_name(field->get_name()) << "(" << field->get_key() << ", \"" @@ -461,49 +459,49 @@ void t_kotlin_generator::generate_struct_field_name_constants(std::ostream& out, if (first) { indent(out); } - out << ";" << endl << endl; + out << ";" << '\n' << '\n'; } // methods - indent(out) << "override fun getThriftFieldId() = thriftFieldId" << endl << endl; - indent(out) << "override fun getFieldName() = fieldName" << endl << endl; + indent(out) << "override fun getThriftFieldId() = thriftFieldId" << '\n' << '\n'; + indent(out) << "override fun getFieldName() = fieldName" << '\n' << '\n'; // companion object - indent(out) << "companion object {" << endl; + indent(out) << "companion object {" << '\n'; indent_up(); { - indent(out) << "@kotlin.jvm.JvmStatic" << endl; - indent(out) << "fun findByValue(value: kotlin.Int): _Fields? {" << endl; + indent(out) << "@kotlin.jvm.JvmStatic" << '\n'; + indent(out) << "fun findByValue(value: kotlin.Int): _Fields? {" << '\n'; indent_up(); { - indent(out) << "return when (value) {" << endl; + indent(out) << "return when (value) {" << '\n'; indent_up(); { for (auto& field : tstruct->get_members()) { - indent(out) << field->get_key() << " -> " << constant_name(field->get_name()) << endl; + indent(out) << field->get_key() << " -> " << constant_name(field->get_name()) << '\n'; } - indent(out) << "else -> null" << endl; + indent(out) << "else -> null" << '\n'; } scope_down(out); } scope_down(out); } - out << endl; + out << '\n'; { - indent(out) << "@kotlin.jvm.JvmStatic" << endl; - indent(out) << "fun findByName(name: kotlin.String): _Fields? {" << endl; + indent(out) << "@kotlin.jvm.JvmStatic" << '\n'; + indent(out) << "fun findByName(name: kotlin.String): _Fields? {" << '\n'; indent_up(); { - indent(out) << "return when (name) {" << endl; + indent(out) << "return when (name) {" << '\n'; indent_up(); { for (auto& field : tstruct->get_members()) { indent(out) << "\"" << field->get_name() << "\"" - << " -> " << constant_name(field->get_name()) << endl; + << " -> " << constant_name(field->get_name()) << '\n'; } - indent(out) << "else -> null" << endl; + indent(out) << "else -> null" << '\n'; } scope_down(out); } @@ -513,16 +511,16 @@ void t_kotlin_generator::generate_struct_field_name_constants(std::ostream& out, scope_down(out); } scope_down(out); - out << endl; + out << '\n'; } void t_kotlin_generator::generate_struct_companion_object(std::ostream& out, t_struct* tstruct) { - indent(out) << "companion object {" << endl; + indent(out) << "companion object {" << '\n'; indent_up(); { indent(out) << "private val STRUCT_DESC: org.apache.thrift.protocol.TStruct = " "org.apache.thrift.protocol.TStruct(\"" - << tstruct->get_name() << "\")" << endl; + << tstruct->get_name() << "\")" << '\n'; { for (auto& field : tstruct->get_members()) { // field desc @@ -530,15 +528,15 @@ void t_kotlin_generator::generate_struct_companion_object(std::ostream& out, t_s << "_FIELD_DESC: org.apache.thrift.protocol.TField = " "org.apache.thrift.protocol.TField(\"" << field->get_name() << "\", " << type_to_enum(field->get_type()) << ", " - << field->get_key() << ")" << endl; + << field->get_key() << ")" << '\n'; // field metadata indent(out) << "private val " << constant_name(field->get_name()) << "_FIELD_META_DATA: org.apache.thrift.meta_data.FieldMetaData = " "org.apache.thrift.meta_data.FieldMetaData(" - << endl; + << '\n'; indent_up(); { - indent(out) << '"' << field->get_name() << '"' << ',' << endl; + indent(out) << '"' << field->get_name() << '"' << ',' << '\n'; indent(out) << "org.apache.thrift.TFieldRequirementType."; if (field->get_req() == t_field::T_REQUIRED) { out << "REQUIRED"; @@ -547,12 +545,12 @@ void t_kotlin_generator::generate_struct_companion_object(std::ostream& out, t_s } else { out << "DEFAULT"; } - out << ',' << endl; + out << ',' << '\n'; generate_field_value_meta_data(indent(out), field->get_type()); - out << ',' << endl; + out << ',' << '\n'; generate_metadata_for_field_annotations(indent(out), field); } - out << ")" << endl; + out << ")" << '\n'; indent_down(); } } @@ -560,23 +558,23 @@ void t_kotlin_generator::generate_struct_companion_object(std::ostream& out, t_s // all fields in a map indent(out) << "private val metadata: Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> = mapOf(" - << endl; + << '\n'; indent_up(); for (auto& field : tstruct->get_members()) { indent(out) << "_Fields." << constant_name(field->get_name()) << " to " - << constant_name(field->get_name()) << "_FIELD_META_DATA," << endl; + << constant_name(field->get_name()) << "_FIELD_META_DATA," << '\n'; } indent_down(); - indent(out) << ")" << endl; + indent(out) << ")" << '\n'; - indent(out) << "init {" << endl; + indent(out) << "init {" << '\n'; indent_up(); indent(out) << "org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(" - << tstruct->get_name() << "::class.java, metadata)" << endl; + << tstruct->get_name() << "::class.java, metadata)" << '\n'; scope_down(out); } scope_down(out); - out << endl; + out << '\n'; } void t_kotlin_generator::generate_metadata_for_field_annotations(std::ostream& out, @@ -584,10 +582,10 @@ void t_kotlin_generator::generate_metadata_for_field_annotations(std::ostream& o if (field->annotations_.size() == 0) { out << "emptyMap()"; } else { - out << "mapOf(" << endl; + out << "mapOf(" << '\n'; indent_up(); for (auto& annotation : field->annotations_) { - indent(out) << "\"" + annotation.first + "\" to \"" + annotation.second.back() + "\"," << endl; + indent(out) << "\"" + annotation.first + "\" to \"" + annotation.second.back() + "\"," << '\n'; } indent_down(); indent(out) << ")"; @@ -602,24 +600,24 @@ void t_kotlin_generator::generate_field_value_meta_data(std::ostream& out, t_typ out << "StructMetaData(" << ttype_class << "STRUCT, " << type_name(type) << "::class.java"; } else if (type->is_container()) { if (type->is_list()) { - out << "ListMetaData(" << ttype_class << "LIST," << endl; + out << "ListMetaData(" << ttype_class << "LIST," << '\n'; indent_up(); t_type* elem_type = ((t_list*)type)->get_elem_type(); generate_field_value_meta_data(indent(out), elem_type); indent_down(); } else if (type->is_set()) { - out << "SetMetaData(" << ttype_class << "SET," << endl; + out << "SetMetaData(" << ttype_class << "SET," << '\n'; indent_up(); t_type* elem_type = ((t_set*)type)->get_elem_type(); generate_field_value_meta_data(indent(out), elem_type); indent_down(); } else { - out << "MapMetaData(" << ttype_class << "MAP," << endl; + out << "MapMetaData(" << ttype_class << "MAP," << '\n'; indent_up(); t_type* key_type = ((t_map*)type)->get_key_type(); t_type* val_type = ((t_map*)type)->get_val_type(); generate_field_value_meta_data(indent(out), key_type); - out << "," << endl; + out << "," << '\n'; generate_field_value_meta_data(indent(out), val_type); indent_down(); } @@ -649,30 +647,30 @@ void t_kotlin_generator::generate_struct_method_get_metadata(std::ostream& out) } void t_kotlin_generator::generate_struct_method_deep_copy(std::ostream& out, t_struct* tstruct) { - indent(out) << "override fun deepCopy(): " << tstruct->get_name() << " {" << endl; + indent(out) << "override fun deepCopy(): " << tstruct->get_name() << " {" << '\n'; indent_up(); { - indent(out) << "return " << tstruct->get_name() << " (" << endl; + indent(out) << "return " << tstruct->get_name() << " (" << '\n'; indent_up(); { for (auto& field : tstruct->get_members()) { - indent(out) << kotlin_safe_name(field->get_name()) << "," << endl; + indent(out) << kotlin_safe_name(field->get_name()) << "," << '\n'; } } indent_down(); - indent(out) << ")" << endl; + indent(out) << ")" << '\n'; } scope_down(out); - out << endl; + out << '\n'; } void t_kotlin_generator::generate_struct_method_compare_to(std::ostream& out, t_struct* tstruct) { indent(out) << "override fun compareTo(other: " << tstruct->get_name() << "?): kotlin.Int {" - << endl; + << '\n'; indent_up(); { indent(out) << "val comparator = compareBy<" << tstruct->get_name() - << "> { it::class.java.name }" << endl; + << "> { it::class.java.name }" << '\n'; indent_up(); for (auto& field : tstruct->get_members()) { indent(out) << ".thenBy"; @@ -681,33 +679,33 @@ void t_kotlin_generator::generate_struct_method_compare_to(std::ostream& out, t_ || field_type->is_binary()) { out << "(org.apache.thrift.TBaseHelper::compareTo)"; } - out << " { it." << kotlin_safe_name(field->get_name()) << " } " << endl; + out << " { it." << kotlin_safe_name(field->get_name()) << " } " << '\n'; } indent_down(); - indent(out) << "return nullsFirst(comparator).compare(this, other)" << endl; + indent(out) << "return nullsFirst(comparator).compare(this, other)" << '\n'; } scope_down(out); - out << endl; + out << '\n'; } void t_kotlin_generator::generate_struct_method_field_for_id(std::ostream& out, t_struct* /*tstruct*/) { - indent(out) << "override fun fieldForId(fieldId: kotlin.Int): _Fields {" << endl; + indent(out) << "override fun fieldForId(fieldId: kotlin.Int): _Fields {" << '\n'; indent_up(); { indent(out) << "return _Fields.findByValue(fieldId) ?: throw " "kotlin.IllegalArgumentException(\"invalid fieldId $fieldId\")" - << endl; + << '\n'; } scope_down(out); - out << endl; + out << '\n'; } void t_kotlin_generator::generate_struct_method_is_set(std::ostream& out, t_struct* tstruct) { - indent(out) << "override fun isSet(field: _Fields): kotlin.Boolean {" << endl; + indent(out) << "override fun isSet(field: _Fields): kotlin.Boolean {" << '\n'; indent_up(); { - indent(out) << "return when (field) {" << endl; + indent(out) << "return when (field) {" << '\n'; indent_up(); { auto members = tstruct->get_members(); @@ -719,67 +717,67 @@ void t_kotlin_generator::generate_struct_method_is_set(std::ostream& out, t_stru } else { out << "this." << kotlin_safe_name(field->get_name()) << " != null"; } - out << endl; + out << '\n'; } } else { - indent(out) << "else -> false" << endl; + indent(out) << "else -> false" << '\n'; } } scope_down(out); } scope_down(out); - out << endl; + out << '\n'; } void t_kotlin_generator::generate_struct_method_clear(std::ostream& out, t_struct* tstruct) { - indent(out) << "override fun clear(): kotlin.Unit {" << endl; + indent(out) << "override fun clear(): kotlin.Unit {" << '\n'; indent_up(); { for (auto& field : tstruct->get_members()) { auto is_required = field->get_req() == t_field::T_REQUIRED; indent(out) << (is_required ? "_" + field->get_name() : kotlin_safe_name(field->get_name())) - << " = null" << endl; + << " = null" << '\n'; } } scope_down(out); - out << endl; + out << '\n'; } void t_kotlin_generator::generate_struct_method_validate(std::ostream& out, t_struct* tstruct) { - indent(out) << "@kotlin.jvm.Throws(org.apache.thrift.TException::class)" << endl; - indent(out) << "fun validate(): kotlin.Unit {" << endl; + indent(out) << "@kotlin.jvm.Throws(org.apache.thrift.TException::class)" << '\n'; + indent(out) << "fun validate(): kotlin.Unit {" << '\n'; indent_up(); { for (auto& field : tstruct->get_members()) { bool is_required = field->get_req() == t_field::T_REQUIRED; if (is_required) { - indent(out) << "if (_" << field->get_name() << " == null) {" << endl; + indent(out) << "if (_" << field->get_name() << " == null) {" << '\n'; indent_up(); { indent(out) << "throw org.apache.thrift.TException(\"Required field `" << field->get_name() << "' is null, " "struct is: $this\")" - << endl; + << '\n'; } scope_down(out); } } } scope_down(out); - out << endl; + out << '\n'; } void t_kotlin_generator::generate_struct_method_set_field_value(std::ostream& out, t_struct* tstruct) { - indent(out) << "@Suppress(\"UNCHECKED_CAST\")" << endl; + indent(out) << "@Suppress(\"UNCHECKED_CAST\")" << '\n'; indent(out) << "override fun setFieldValue(field: _Fields, value: kotlin.Any?): kotlin.Unit {" - << endl; + << '\n'; indent_up(); { const vector& members = tstruct->get_members(); if (members.size() > 0) { - indent(out) << "when (field) {" << endl; + indent(out) << "when (field) {" << '\n'; indent_up(); { for (auto& field : tstruct->get_members()) { @@ -787,155 +785,155 @@ void t_kotlin_generator::generate_struct_method_set_field_value(std::ostream& ou indent(out) << "_Fields." << constant_name(field->get_name()) << " -> this." << (is_required ? "_" + field->get_name() : kotlin_safe_name(field->get_name())) - << " = value as " << type_name(field->get_type()) << "?" << endl; + << " = value as " << type_name(field->get_type()) << "?" << '\n'; } } scope_down(out); } else { - indent(out) << "return" << endl; + indent(out) << "return" << '\n'; } } scope_down(out); - out << endl; + out << '\n'; } void t_kotlin_generator::generate_struct_method_get_field_value(std::ostream& out, t_struct* tstruct) { - indent(out) << "override fun getFieldValue(field: _Fields): kotlin.Any? {" << endl; + indent(out) << "override fun getFieldValue(field: _Fields): kotlin.Any? {" << '\n'; indent_up(); { auto members = tstruct->get_members(); if (members.size() > 0) { - indent(out) << "return when (field) {" << endl; + indent(out) << "return when (field) {" << '\n'; indent_up(); { for (auto& field : tstruct->get_members()) { indent(out) << "_Fields." << constant_name(field->get_name()) << " -> this." - << kotlin_safe_name(field->get_name()) << endl; + << kotlin_safe_name(field->get_name()) << '\n'; } } scope_down(out); } else { - indent(out) << "return null" << endl; + indent(out) << "return null" << '\n'; } } scope_down(out); - out << endl; + out << '\n'; } void t_kotlin_generator::generate_struct_method_read(std::ostream& out, t_struct* tstruct) { indent(out) << "override fun read(iproto: org.apache.thrift.protocol.TProtocol): kotlin.Unit {" - << endl; + << '\n'; indent_up(); { indent(out) << "require(org.apache.thrift.scheme.StandardScheme::class.java == iproto.scheme) { " "\"only standard scheme is " "supported for now\" }" - << endl; - indent(out) << tstruct->get_name() << "StandardScheme.read(iproto, this)" << endl; + << '\n'; + indent(out) << tstruct->get_name() << "StandardScheme.read(iproto, this)" << '\n'; } scope_down(out); - out << endl; + out << '\n'; } void t_kotlin_generator::generate_struct_method_write(std::ostream& out, t_struct* tstruct) { indent(out) << "override fun write(oproto: org.apache.thrift.protocol.TProtocol): kotlin.Unit {" - << endl; + << '\n'; indent_up(); { indent(out) << "require(org.apache.thrift.scheme.StandardScheme::class.java == oproto.scheme) { " "\"only standard scheme is " "supported for now\" }" - << endl; - indent(out) << tstruct->get_name() << "StandardScheme.write(oproto, this)" << endl; + << '\n'; + indent(out) << tstruct->get_name() << "StandardScheme.write(oproto, this)" << '\n'; } scope_down(out); - out << endl; + out << '\n'; } void t_kotlin_generator::generate_struct_standard_scheme_read(std::ostream& out, t_struct* tstruct) { indent(out) << "override fun read(iproto: org.apache.thrift.protocol.TProtocol, struct: " - << tstruct->get_name() << ") {" << endl; + << tstruct->get_name() << ") {" << '\n'; indent_up(); { - indent(out) << "iproto.apply {" << endl; + indent(out) << "iproto.apply {" << '\n'; indent_up(); { - indent(out) << "readStruct {" << endl; + indent(out) << "readStruct {" << '\n'; indent_up(); { - indent(out) << "var stopped = false" << endl; - indent(out) << "while (!stopped) {" << endl; + indent(out) << "var stopped = false" << '\n'; + indent(out) << "while (!stopped) {" << '\n'; indent_up(); { - indent(out) << "stopped = readField {" << endl; + indent(out) << "stopped = readField {" << '\n'; indent_up(); { indent(out) << "val skipNext = { " "org.apache.thrift.protocol.TProtocolUtil.skip(iproto, it.type) }" - << endl; + << '\n'; - indent(out) << "when (it.id.toInt()) {" << endl; + indent(out) << "when (it.id.toInt()) {" << '\n'; indent_up(); { for (auto& field : tstruct->get_members()) { - indent(out) << field->get_key() << " -> {" << endl; + indent(out) << field->get_key() << " -> {" << '\n'; indent_up(); { indent(out) << "if (it.type == " << type_to_enum(field->get_type()) << ") {" - << endl; + << '\n'; indent_up(); generate_deserialize_field(out, field, "struct."); indent_down(); - indent(out) << "} else {" << endl; + indent(out) << "} else {" << '\n'; indent_up(); - indent(out) << "skipNext()" << endl; + indent(out) << "skipNext()" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } scope_down(out); } - indent(out) << "else -> skipNext()" << endl; + indent(out) << "else -> skipNext()" << '\n'; } scope_down(out); } scope_down(out); } scope_down(out); - indent(out) << "struct.validate()" << endl; + indent(out) << "struct.validate()" << '\n'; } scope_down(out); } scope_down(out); } scope_down(out); - out << endl; + out << '\n'; } void t_kotlin_generator::generate_struct_standard_scheme_write(std::ostream& out, t_struct* tstruct) { indent(out) << "override fun write(oproto: org.apache.thrift.protocol.TProtocol, struct: " - << tstruct->get_name() << ") {" << endl; + << tstruct->get_name() << ") {" << '\n'; indent_up(); { - indent(out) << "struct.validate()" << endl; - indent(out) << "oproto.apply {" << endl; + indent(out) << "struct.validate()" << '\n'; + indent(out) << "oproto.apply {" << '\n'; indent_up(); { - indent(out) << "writeStruct(STRUCT_DESC) {" << endl; + indent(out) << "writeStruct(STRUCT_DESC) {" << '\n'; indent_up(); { for (auto& field : tstruct->get_members()) { auto is_required = field->get_req() == t_field::T_REQUIRED; indent(out) << "struct." << kotlin_safe_name(field->get_name()) << (is_required ? "" : "?") << ".let { " - << kotlin_safe_name(field->get_name()) << " ->" << endl; + << kotlin_safe_name(field->get_name()) << " ->" << '\n'; indent_up(); { indent(out) << "writeField(" << constant_name(field->get_name()) << "_FIELD_DESC) {" - << endl; + << '\n'; indent_up(); generate_serialize_field(out, field); scope_down(out); @@ -943,36 +941,36 @@ void t_kotlin_generator::generate_struct_standard_scheme_write(std::ostream& out scope_down(out); } } - indent(out) << "writeFieldStop()" << endl; + indent(out) << "writeFieldStop()" << '\n'; scope_down(out); } scope_down(out); } scope_down(out); - out << endl; + out << '\n'; } void t_kotlin_generator::generate_struct_standard_scheme(std::ostream& out, t_struct* tstruct) { indent(out) << "private object " << tstruct->get_name() << "StandardScheme : org.apache.thrift.scheme.StandardScheme<" << tstruct->get_name() - << ">() {" << endl; + << ">() {" << '\n'; indent_up(); generate_struct_standard_scheme_read(out, tstruct); generate_struct_standard_scheme_write(out, tstruct); scope_down(out); - out << endl; + out << '\n'; } void t_kotlin_generator::generate_union_tuple_scheme(std::ostream& out, t_struct* /*tunion*/) { indent(out) << "override fun tupleSchemeReadValue(iproto: org.apache.thrift.protocol.TProtocol, " "fieldID: kotlin.Short) = throw kotlin.UnsupportedOperationException(\"only " "standard scheme is supported for now\")" - << endl; + << '\n'; indent(out) << "override fun tupleSchemeWriteValue(oproto: org.apache.thrift.protocol.TProtocol) = " "throw kotlin.UnsupportedOperationException(\"only standard scheme is supported for " "now\")" - << endl; + << '\n'; } void t_kotlin_generator::generate_union_standard_scheme(std::ostream& out, t_struct* tunion) { @@ -984,61 +982,61 @@ void t_kotlin_generator::generate_union_standard_scheme_read(std::ostream& out, indent(out) << "override fun standardSchemeReadValue(iproto: org.apache.thrift.protocol.TProtocol, " "field: org.apache.thrift.protocol.TField): Any? =" - << endl; + << '\n'; indent_up(); - indent(out) << "when (_Fields.findByValue(field.id.toInt())) {" << endl; + indent(out) << "when (_Fields.findByValue(field.id.toInt())) {" << '\n'; indent_up(); for (auto& member : tunion->get_members()) { auto expect_type = type_name(member->get_type()); - indent(out) << "_Fields." << constant_name(member->get_name()) << " -> {" << endl; + indent(out) << "_Fields." << constant_name(member->get_name()) << " -> {" << '\n'; indent_up(); { indent(out) << "if (field.type == " << constant_name(member->get_name()) - << "_FIELD_DESC.type) {" << endl; + << "_FIELD_DESC.type) {" << '\n'; indent_up(); - indent(out) << "iproto.run {" << endl; + indent(out) << "iproto.run {" << '\n'; indent_up(); indent(out); generate_deserialize_value(out, member->get_type()); - out << endl; + out << '\n'; scope_down(out); indent_down(); - indent(out) << "} else {" << endl; + indent(out) << "} else {" << '\n'; indent_up(); - indent(out) << "org.apache.thrift.protocol.TProtocolUtil.skip(iproto, field.type)" << endl; - indent(out) << "null" << endl; + indent(out) << "org.apache.thrift.protocol.TProtocolUtil.skip(iproto, field.type)" << '\n'; + indent(out) << "null" << '\n'; scope_down(out); } scope_down(out); } - indent(out) << "null -> {" << endl; + indent(out) << "null -> {" << '\n'; indent_up(); - indent(out) << "org.apache.thrift.protocol.TProtocolUtil.skip(iproto, field.type)" << endl; - indent(out) << "null" << endl; + indent(out) << "org.apache.thrift.protocol.TProtocolUtil.skip(iproto, field.type)" << '\n'; + indent(out) << "null" << '\n'; scope_down(out); scope_down(out); indent_down(); } void t_kotlin_generator::generate_union_standard_scheme_write(std::ostream& out, t_struct* tunion) { - indent(out) << "@Suppress(\"UNCHECKED_CAST\")" << endl; + indent(out) << "@Suppress(\"UNCHECKED_CAST\")" << '\n'; indent(out) << "override fun standardSchemeWriteValue(oproto: org.apache.thrift.protocol.TProtocol) {" - << endl; + << '\n'; indent_up(); - indent(out) << "when (setField_) {" << endl; + indent(out) << "when (setField_) {" << '\n'; indent_up(); for (auto& member : tunion->get_members()) { - indent(out) << "_Fields." << constant_name(member->get_name()) << " -> {" << endl; + indent(out) << "_Fields." << constant_name(member->get_name()) << " -> {" << '\n'; indent_up(); { - indent(out) << "val it = value_ as " << type_name(member->get_type()) << endl; - indent(out) << "oproto.apply {" << endl; + indent(out) << "val it = value_ as " << type_name(member->get_type()) << '\n'; + indent(out) << "oproto.apply {" << '\n'; indent_up(); { indent(out); generate_serialize_value(out, member->get_type()); - out << endl; + out << '\n'; } scope_down(out); } @@ -1046,7 +1044,7 @@ void t_kotlin_generator::generate_union_standard_scheme_write(std::ostream& out, } indent(out) << "null -> throw kotlin.IllegalStateException(\"Cannot write union with unknown " "field $setField_\")" - << endl; + << '\n'; scope_down(out); scope_down(out); } @@ -1066,25 +1064,25 @@ void t_kotlin_generator::generate_union_methods_definitions(std::ostream& out, t } auto union_class_name = kotlin_safe_name(tunion->get_name()); - { indent(out) << "override fun deepCopy() = " << union_class_name << "(this)" << endl; } - { indent(out) << "override fun enumForId(id: kotlin.Short) = fieldForId(id.toInt())" << endl; } - { indent(out) << "override fun getStructDesc() = STRUCT_DESC" << endl; } + { indent(out) << "override fun deepCopy() = " << union_class_name << "(this)" << '\n'; } + { indent(out) << "override fun enumForId(id: kotlin.Short) = fieldForId(id.toInt())" << '\n'; } + { indent(out) << "override fun getStructDesc() = STRUCT_DESC" << '\n'; } { - indent(out) << "override fun getFieldDesc(setField: _Fields) = when (setField) {" << endl; + indent(out) << "override fun getFieldDesc(setField: _Fields) = when (setField) {" << '\n'; indent_up(); for (auto& member : tunion->get_members()) { indent(out) << "_Fields." << constant_name(member->get_name()) << " -> " - << constant_name(member->get_name()) << "_FIELD_DESC" << endl; + << constant_name(member->get_name()) << "_FIELD_DESC" << '\n'; } scope_down(out); } } void t_kotlin_generator::generate_union_method_check_type(std::ostream& out, t_struct* tunion) { - indent(out) << "@Suppress(\"UNCHECKED_CAST\")" << endl; - indent(out) << "override fun checkType(setField: _Fields, value: kotlin.Any?) {" << endl; + indent(out) << "@Suppress(\"UNCHECKED_CAST\")" << '\n'; + indent(out) << "override fun checkType(setField: _Fields, value: kotlin.Any?) {" << '\n'; indent_up(); - indent(out) << "when (setField) {" << endl; + indent(out) << "when (setField) {" << '\n'; indent_up(); for (auto& member : tunion->get_members()) { auto expect_type = type_name(member->get_type()); @@ -1092,7 +1090,7 @@ void t_kotlin_generator::generate_union_method_check_type(std::ostream& out, t_s << expect_type << " ?: throw kotlin.ClassCastException(\"Was expecting value of type `" << expect_type << "' for field `" << member->get_name() - << "', but got ${value?.javaClass}\")" << endl; + << "', but got ${value?.javaClass}\")" << '\n'; } scope_down(out); scope_down(out); @@ -1103,12 +1101,12 @@ void t_kotlin_generator::generate_union_definition(std::ostream& out, string /*additional interface*/) { auto union_class_name = kotlin_safe_name(tunion->get_name()); indent(out) << "class " << union_class_name << " : org.apache.thrift.TUnion<" << union_class_name - << ", " << union_class_name << "._Fields> {" << endl; + << ", " << union_class_name << "._Fields> {" << '\n'; indent_up(); indent(out) << "constructor(setField: _Fields, value: kotlin.Any) : super(setField, value)" - << endl; - indent(out) << "constructor(other: " << union_class_name << ") : super(other)" << endl; - indent(out) << "constructor() : super()" << endl; + << '\n'; + indent(out) << "constructor(other: " << union_class_name << ") : super(other)" << '\n'; + indent(out) << "constructor() : super()" << '\n'; generate_struct_field_name_constants(out, tunion); generate_struct_companion_object(out, tunion); @@ -1120,7 +1118,7 @@ void t_kotlin_generator::generate_union_definition(std::ostream& out, generate_union_standard_scheme(out, tunion); generate_union_tuple_scheme(out, tunion); indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } void t_kotlin_generator::generate_struct_definition(std::ostream& out, @@ -1139,7 +1137,7 @@ void t_kotlin_generator::generate_struct_definition(std::ostream& out, indent_up(); auto sep = ""; for (auto field : members) { - out << sep << endl; + out << sep << '\n'; sep = ","; generate_kdoc_comment(out, field); auto is_required = field->get_req() == t_field::T_REQUIRED; @@ -1157,7 +1155,7 @@ void t_kotlin_generator::generate_struct_definition(std::ostream& out, out << ": " << type_name(field->get_type()) << "? = null"; } indent_down(); - out << endl; + out << '\n'; indent(out) << ") : "; if (is_exception) { out << "org.apache.thrift.TException(), "; @@ -1166,7 +1164,7 @@ void t_kotlin_generator::generate_struct_definition(std::ostream& out, additional_interface = ", " + additional_interface; } out << "org.apache.thrift.TBase<" << tstruct->get_name() << ", " << tstruct->get_name() - << "._Fields>" << additional_interface << " {" << endl; + << "._Fields>" << additional_interface << " {" << '\n'; indent_up(); @@ -1178,7 +1176,7 @@ void t_kotlin_generator::generate_struct_definition(std::ostream& out, out << "override "; } out << "val " << kotlin_safe_name(field->get_name()) << ": " << type_name(field->get_type()) - << " get() = _" + kotlin_safe_name(field->get_name()) << "!!" << endl; + << " get() = _" + kotlin_safe_name(field->get_name()) << "!!" << '\n'; } } @@ -1199,7 +1197,7 @@ void t_kotlin_generator::generate_struct_definition(std::ostream& out, generate_struct_method_write(out, tstruct); indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } string t_kotlin_generator::base_type_write_expression(t_base_type* tbase, string it) { @@ -1304,7 +1302,7 @@ void t_kotlin_generator::generate_serialize_field(ostream& out, t_field* tfield) } indent(out); generate_serialize_value(out, type, kotlin_safe_name(tfield->get_name())); - out << endl; + out << '\n'; } /** @@ -1323,7 +1321,7 @@ void t_kotlin_generator::generate_deserialize_field(ostream& out, t_field* tfiel = prefix + (is_required ? "_" + tfield->get_name() : kotlin_safe_name(tfield->get_name())); indent(out) << name << " = "; generate_deserialize_value(out, type); - out << endl; + out << '\n'; } /** @@ -1333,33 +1331,33 @@ void t_kotlin_generator::generate_serialize_container(ostream& out, t_type* ttyp if (ttype->is_map()) { out << "writeMap(" << type_to_enum(((t_map*)ttype)->get_key_type()) << ", " << type_to_enum(((t_map*)ttype)->get_val_type()) << ", " << it << ") { (key, value) ->" - << endl; + << '\n'; indent_up(); { generate_serialize_value(indent(out), ((t_map*)ttype)->get_key_type(), "key"); - out << endl; + out << '\n'; generate_serialize_value(indent(out), ((t_map*)ttype)->get_val_type(), "value"); - out << endl; + out << '\n'; indent_down(); } indent(out) << "}"; } else if (ttype->is_set()) { out << "writeSet(" << type_to_enum(((t_set*)ttype)->get_elem_type()) << ", " << it << ") {" - << endl; + << '\n'; indent_up(); { generate_serialize_value(indent(out), ((t_set*)ttype)->get_elem_type()); - out << endl; + out << '\n'; indent_down(); } indent(out) << "}"; } else if (ttype->is_list()) { out << "writeList(" << type_to_enum(((t_list*)ttype)->get_elem_type()) << ", " << it << ") {" - << endl; + << '\n'; { indent_up(); generate_serialize_value(indent(out), ((t_list*)ttype)->get_elem_type()); - out << endl; + out << '\n'; indent_down(); } indent(out) << "}"; @@ -1373,41 +1371,41 @@ void t_kotlin_generator::generate_serialize_container(ostream& out, t_type* ttyp */ void t_kotlin_generator::generate_deserialize_container(ostream& out, t_type* ttype) { if (ttype->is_map()) { - out << "readMap { tmap ->" << endl; + out << "readMap { tmap ->" << '\n'; indent_up(); - indent(out) << "kotlin.collections.List(tmap.size) {" << endl; + indent(out) << "kotlin.collections.List(tmap.size) {" << '\n'; indent_up(); indent(out); generate_deserialize_value(out, ((t_map*)ttype)->get_key_type()); out << " to "; generate_deserialize_value(out, ((t_map*)ttype)->get_val_type()); - out << endl; + out << '\n'; indent_down(); - indent(out) << "}.associate { it }" << endl; + indent(out) << "}.associate { it }" << '\n'; indent_down(); indent(out) << "}"; } else if (ttype->is_set()) { - out << "readSet { tset ->" << endl; + out << "readSet { tset ->" << '\n'; indent_up(); - indent(out) << "kotlin.collections.List(tset.size) {" << endl; + indent(out) << "kotlin.collections.List(tset.size) {" << '\n'; indent_up(); indent(out); generate_deserialize_value(out, ((t_set*)ttype)->get_elem_type()); - out << endl; + out << '\n'; indent_down(); - indent(out) << "}.toSet()" << endl; + indent(out) << "}.toSet()" << '\n'; indent_down(); indent(out) << "}"; } else if (ttype->is_list()) { - out << "readList { tlist ->" << endl; + out << "readList { tlist ->" << '\n'; indent_up(); - indent(out) << "kotlin.collections.List(tlist.size) {" << endl; + indent(out) << "kotlin.collections.List(tlist.size) {" << '\n'; indent_up(); indent(out); generate_deserialize_value(out, ((t_list*)ttype)->get_elem_type()); - out << endl; + out << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; indent_down(); indent(out) << "}"; } else { @@ -1437,14 +1435,14 @@ void t_kotlin_generator::generate_service_interface(t_service* tservice) { ofstream_with_content_based_conditional_update out; out.open(f_service_name.c_str()); out << autogen_comment() << kotlin_package(); - out << "interface " << tservice->get_name() << " {" << endl; + out << "interface " << tservice->get_name() << " {" << '\n'; indent_up(); for (auto tfunc : tservice->get_functions()) { generate_kdoc_comment(out, tfunc); - indent(out) << function_signature(tfunc) << endl; + indent(out) << function_signature(tfunc) << '\n'; } scope_down(out); - out << endl << endl; + out << '\n' << '\n'; out.close(); } @@ -1455,22 +1453,22 @@ void t_kotlin_generator::generate_service_client(t_service* tservice) { out << autogen_comment() << warning_surpressions() << kotlin_package(); generate_docstring_comment(out, "/**\n", " * ", "client implementation for [" + tservice->get_name() + "]", " */\n"); - indent(out) << "class " << tservice->get_name() << "Client(" << endl; + indent(out) << "class " << tservice->get_name() << "Client(" << '\n'; indent_up(); - indent(out) << "protocolFactory: org.apache.thrift.protocol.TProtocolFactory," << endl; - indent(out) << "clientManager: org.apache.thrift.async.TAsyncClientManager," << endl; - indent(out) << "transport: org.apache.thrift.transport.TNonblockingTransport" << endl; + indent(out) << "protocolFactory: org.apache.thrift.protocol.TProtocolFactory," << '\n'; + indent(out) << "clientManager: org.apache.thrift.async.TAsyncClientManager," << '\n'; + indent(out) << "transport: org.apache.thrift.transport.TNonblockingTransport" << '\n'; indent_down(); out << "): org.apache.thrift.async.TAsyncClient(protocolFactory, clientManager, transport), " - << tservice->get_name() << " {" << endl - << endl; + << tservice->get_name() << " {" << '\n' + << '\n'; indent_up(); { - indent(out) << "private val seqId = java.util.concurrent.atomic.AtomicInteger()" << endl - << endl; + indent(out) << "private val seqId = java.util.concurrent.atomic.AtomicInteger()" << '\n' + << '\n'; for (auto tfunc : tservice->get_functions()) { - indent(out) << "override " << function_signature(tfunc) << " {" << endl; + indent(out) << "override " << function_signature(tfunc) << " {" << '\n'; indent_up(); { string args_name = tservice->get_name() + "FunctionArgs." + tfunc->get_name() + "_args"; @@ -1483,16 +1481,16 @@ void t_kotlin_generator::generate_service_client(t_service* tservice) { first = false; out << tfield->get_name(); } - out << ")" << endl; - indent(out) << "return transformCallback {" << endl; + out << ")" << '\n'; + indent(out) << "return transformCallback {" << '\n'; indent_up(); { - indent(out) << "checkReady()" << endl; + indent(out) << "checkReady()" << '\n'; indent(out) << "___currentMethod = ProcessCall." << tfunc->get_name() << "Call(args, seqId.getAndIncrement(), this, ___protocolFactory, ___transport, it)" - << endl; - indent(out) << "___manager.call(___currentMethod)" << endl; + << '\n'; + indent(out) << "___manager.call(___currentMethod)" << '\n'; } scope_down(out); } @@ -1502,22 +1500,22 @@ void t_kotlin_generator::generate_service_client(t_service* tservice) { indent(out) << "private suspend fun " "org.apache.thrift.async.TAsyncClient.transformCallback(action: " "(org.apache.thrift.async.AsyncMethodCallback) -> Unit): R {" - << endl; + << '\n'; indent_up(); - indent(out) << "val deferred = kotlinx.coroutines.CompletableDeferred()" << endl; + indent(out) << "val deferred = kotlinx.coroutines.CompletableDeferred()" << '\n'; indent(out) << "val callback = object : org.apache.thrift.async.AsyncMethodCallback {" - << endl; + << '\n'; indent_up(); - indent(out) << "override fun onComplete(response: R) { deferred.complete(response) }" << endl; + indent(out) << "override fun onComplete(response: R) { deferred.complete(response) }" << '\n'; indent(out) << "override fun onError(exception: java.lang.Exception) { " "deferred.completeExceptionally(exception) }" - << endl; + << '\n'; scope_down(out); - indent(out) << "action(callback)" << endl; - indent(out) << "return deferred.await()" << endl; + indent(out) << "action(callback)" << '\n'; + indent(out) << "return deferred.await()" << '\n'; scope_down(out); - indent(out) << "sealed interface ProcessCall {" << endl; + indent(out) << "sealed interface ProcessCall {" << '\n'; indent_up(); for (auto tfunc : tservice->get_functions()) { generate_client_call(out, tservice, tfunc); @@ -1525,7 +1523,7 @@ void t_kotlin_generator::generate_service_client(t_service* tservice) { scope_down(out); } scope_down(out); - out << endl << endl; + out << '\n' << '\n'; out.close(); } @@ -1536,74 +1534,74 @@ void t_kotlin_generator::generate_client_call(std::ostream& out, string funclassname = funname + "Call"; string rtype = type_name(tfunc->get_returntype(), true); - indent(out) << "class " + funclassname + "(" << endl; + indent(out) << "class " + funclassname + "(" << '\n'; indent_up(); string args_name = tservice->get_name() + "FunctionArgs." + tfunc->get_name() + "_args"; - indent(out) << "val args: " << args_name << "," << endl; - indent(out) << "val seqId: kotlin.Int," << endl; - indent(out) << "client: org.apache.thrift.async.TAsyncClient," << endl; - indent(out) << "protocolFactory: org.apache.thrift.protocol.TProtocolFactory," << endl; - indent(out) << "transport: org.apache.thrift.transport.TNonblockingTransport," << endl; + indent(out) << "val args: " << args_name << "," << '\n'; + indent(out) << "val seqId: kotlin.Int," << '\n'; + indent(out) << "client: org.apache.thrift.async.TAsyncClient," << '\n'; + indent(out) << "protocolFactory: org.apache.thrift.protocol.TProtocolFactory," << '\n'; + indent(out) << "transport: org.apache.thrift.transport.TNonblockingTransport," << '\n'; indent(out) << "resultHandler: org.apache.thrift.async.AsyncMethodCallback<" << rtype << ">," - << endl; + << '\n'; indent_down(); indent(out) << ") : org.apache.thrift.async.TAsyncMethodCall<" << rtype << ">(client, protocolFactory, transport, resultHandler, " - << (tfunc->is_oneway() ? "true" : "false") << "), ProcessCall {" << endl; + << (tfunc->is_oneway() ? "true" : "false") << "), ProcessCall {" << '\n'; indent_up(); indent(out) << "override fun write_args(protocol: org.apache.thrift.protocol.TProtocol) {" - << endl; + << '\n'; indent_up(); indent(out) << "val marker = org.apache.thrift.protocol.TMessage(\"" << tfunc->get_name() - << "\", org.apache.thrift.protocol.TMessageType.CALL, seqId)" << endl; - indent(out) << "protocol.writeMessage(marker) { args.write(protocol) }" << endl; + << "\", org.apache.thrift.protocol.TMessageType.CALL, seqId)" << '\n'; + indent(out) << "protocol.writeMessage(marker) { args.write(protocol) }" << '\n'; scope_down(out); - indent(out) << "override fun getResult(): " << rtype << " {" << endl; + indent(out) << "override fun getResult(): " << rtype << " {" << '\n'; indent_up(); indent(out) << "check(state == org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) { " "\"Method call not finished!\" }" - << endl; + << '\n'; indent(out) << "val memoryTransport = " "org.apache.thrift.transport.TMemoryInputTransport(frameBuffer.array())" - << endl; - indent(out) << "val protocol = client.protocolFactory.getProtocol(memoryTransport)" << endl; + << '\n'; + indent(out) << "val protocol = client.protocolFactory.getProtocol(memoryTransport)" << '\n'; if (tfunc->is_oneway()) { - indent(out) << "// one way function, nothing to read" << endl; + indent(out) << "// one way function, nothing to read" << '\n'; } else { - indent(out) << "return protocol.readMessage {" << endl; + indent(out) << "return protocol.readMessage {" << '\n'; indent_up(); { - indent(out) << "if (it.type == org.apache.thrift.protocol.TMessageType.EXCEPTION) {" << endl; + indent(out) << "if (it.type == org.apache.thrift.protocol.TMessageType.EXCEPTION) {" << '\n'; indent_up(); indent(out) << "val ex = org.apache.thrift.TApplicationException().apply { read(protocol) }" - << endl; - indent(out) << "throw ex" << endl; + << '\n'; + indent(out) << "throw ex" << '\n'; scope_down(out); - indent(out) << "if (it.seqid != seqId) {" << endl; + indent(out) << "if (it.seqid != seqId) {" << '\n'; indent_up(); - indent(out) << "throw org.apache.thrift.TApplicationException(" << endl; + indent(out) << "throw org.apache.thrift.TApplicationException(" << '\n'; indent_up(); - indent(out) << "org.apache.thrift.TApplicationException.BAD_SEQUENCE_ID," << endl; + indent(out) << "org.apache.thrift.TApplicationException.BAD_SEQUENCE_ID," << '\n'; indent(out) << "\"" << funname << " failed: out of sequence response: expected $seqId but got ${it.seqid}\"" - << endl; + << '\n'; indent_down(); - indent(out) << ")" << endl; + indent(out) << ")" << '\n'; scope_down(out); string result_name = tservice->get_name() + "FunctionResult." + tfunc->get_name() + "_result"; - indent(out) << "val result = " << result_name << "().apply { read(protocol) }" << endl; + indent(out) << "val result = " << result_name << "().apply { read(protocol) }" << '\n'; for (auto xception : tfunc->get_xceptions()->get_members()) { - indent(out) << "result." << xception->get_name() << "?.let { throw it }" << endl; + indent(out) << "result." << xception->get_name() << "?.let { throw it }" << '\n'; } if (!tfunc->get_returntype()->is_void()) { indent(out) << "result.success ?: throw " "org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException." "MISSING_RESULT, \"returnString failed: unknown result\")" - << endl; + << '\n'; } } scope_down(out); @@ -1619,43 +1617,43 @@ void t_kotlin_generator::generate_service_processor(t_service* tservice) { out << autogen_comment() << warning_surpressions() << kotlin_package(); auto service_imports = {"import kotlinx.coroutines.future.future"}; for (auto service_import : service_imports) { - out << service_import << endl; + out << service_import << '\n'; } - out << endl; + out << '\n'; generate_docstring_comment(out, "/**\n", " * ", "server implementation for [" + tservice->get_name() + "]", " */\n"); - indent(out) << "class " << tservice->get_name() << "Processor(" << endl; + indent(out) << "class " << tservice->get_name() << "Processor(" << '\n'; indent_up(); - indent(out) << "handler: " << tservice->get_name() << "," << endl; - indent(out) << "private val scope: kotlinx.coroutines.CoroutineScope," << endl; + indent(out) << "handler: " << tservice->get_name() << "," << '\n'; + indent(out) << "private val scope: kotlinx.coroutines.CoroutineScope," << '\n'; indent(out) << "private val processMap: kotlin.collections.Mapget_name() << ", out org.apache.thrift.TBase<*, " - "*>, out kotlin.Any>> = mapOf(" - << endl; + "*>, out kotlin.Any, out org.apache.thrift.TBase<*, *>>> = mapOf(" + << '\n'; indent_up(); { for (auto tfunc : tservice->get_functions()) { indent(out) << '"' << tfunc->get_name() << '"' << " to ProcessFunction." << tfunc->get_name() - << "(scope)," << endl; + << "(scope)," << '\n'; } } indent_down(); - indent(out) << ")" << endl; + indent(out) << ")" << '\n'; indent_down(); out << "): org.apache.thrift.TBaseAsyncProcessor<" << tservice->get_name() - << ">(handler, processMap) {" << endl; + << ">(handler, processMap) {" << '\n'; indent_up(); - indent(out) << "companion object {" << endl; + indent(out) << "companion object {" << '\n'; indent_up(); indent(out) << "internal val logger: org.slf4j.Logger = " "org.slf4j.LoggerFactory.getLogger(" - << tservice->get_name() << "Processor::class.java)" << endl; + << tservice->get_name() << "Processor::class.java)" << '\n'; scope_down(out); - indent(out) << "sealed interface ProcessFunction {" << endl; + indent(out) << "sealed interface ProcessFunction {" << '\n'; indent_up(); { @@ -1665,7 +1663,7 @@ void t_kotlin_generator::generate_service_processor(t_service* tservice) { } scope_down(out); scope_down(out); - out << endl << endl; + out << '\n' << '\n'; out.close(); } @@ -1674,21 +1672,32 @@ void t_kotlin_generator::generate_service_process_function(ostream& out, t_function* tfunc) { string args_name = tservice->get_name() + "FunctionArgs." + tfunc->get_name() + "_args"; string rtype = type_name(tfunc->get_returntype(), true); + string resultname = tservice->get_name() + "FunctionResult." + tfunc->get_name() + "_result"; indent(out) << "class " << tfunc->get_name() << "get_name() << ">(private val scope: kotlinx.coroutines.CoroutineScope) : " "org.apache.thrift.AsyncProcessFunction(\"" << tfunc->get_name() - << "\"), ProcessFunction {" << endl; + << args_name << ", " << rtype << ", " + << (tfunc->is_oneway() ? "org.apache.thrift.TBase<*, *>" : resultname) + << ">(\"" << tfunc->get_name() << "\"), ProcessFunction {" + << '\n'; indent_up(); { - indent(out) << "override fun isOneway() = " << (tfunc->is_oneway() ? "true" : "false") << endl; - indent(out) << "override fun getEmptyArgsInstance() = " << args_name << "()" << endl; + indent(out) << "override fun isOneway() = " << (tfunc->is_oneway() ? "true" : "false") << '\n'; + indent(out) << "override fun getEmptyArgsInstance() = " << args_name << "()" << '\n'; + indent(out) << "override fun getEmptyResultInstance() = "; + if (tfunc->is_oneway()) { + out << "null" << '\n'; + } + else { + out << resultname << "()" << '\n'; + } + indent(out) << '\n'; indent(out) << "override fun start(iface: I, args: " << args_name << ", resultHandler: org.apache.thrift.async.AsyncMethodCallback<" << rtype - << ">) {" << endl; + << ">) {" << '\n'; indent_up(); - indent(out) << "scope.future {" << endl; + indent(out) << "scope.future {" << '\n'; indent_up(); indent(out) << "iface." << tfunc->get_name() << "("; { @@ -1703,18 +1712,18 @@ void t_kotlin_generator::generate_service_process_function(ostream& out, out << "args." << tfield->get_name() << "!!"; } } - out << ")" << endl; + out << ")" << '\n'; indent_down(); - indent(out) << "}.whenComplete { r, t ->" << endl; + indent(out) << "}.whenComplete { r, t ->" << '\n'; { indent_up(); - indent(out) << "if (t != null) {" << endl; + indent(out) << "if (t != null) {" << '\n'; indent_up(); - indent(out) << "resultHandler.onError(t as java.lang.Exception)" << endl; + indent(out) << "resultHandler.onError(t as java.lang.Exception)" << '\n'; indent_down(); - indent(out) << "} else {" << endl; + indent(out) << "} else {" << '\n'; indent_up(); - indent(out) << "resultHandler.onComplete(r)" << endl; + indent(out) << "resultHandler.onComplete(r)" << '\n'; } scope_down(out); scope_down(out); @@ -1723,106 +1732,106 @@ void t_kotlin_generator::generate_service_process_function(ostream& out, indent(out) << "override fun getResultHandler(fb: " "org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer, seqid: " "Int) =" - << endl; + << '\n'; indent_up(); { indent(out) << "object : org.apache.thrift.async.AsyncMethodCallback<" << rtype << ">{" - << endl; + << '\n'; indent_up(); { - indent(out) << "override fun onComplete(response: " << rtype << ") {" << endl; + indent(out) << "override fun onComplete(response: " << rtype << ") {" << '\n'; indent_up(); if (tfunc->is_oneway()) { - indent(out) << "// one way function, no result handling" << endl; + indent(out) << "// one way function, no result handling" << '\n'; } else { string result_name = tservice->get_name() + "FunctionResult." + tfunc->get_name() + "_result"; - indent(out) << "val result = " << result_name << "()" << endl; + indent(out) << "val result = " << result_name << "()" << '\n'; if (!tfunc->get_returntype()->is_void()) { - indent(out) << "result.success = response" << endl; + indent(out) << "result.success = response" << '\n'; } - indent(out) << "try {" << endl; + indent(out) << "try {" << '\n'; indent_up(); indent(out) << "sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY, seqid)" - << endl; + << '\n'; indent_down(); - indent(out) << "} catch (e: org.apache.thrift.transport.TTransportException) {" << endl; + indent(out) << "} catch (e: org.apache.thrift.transport.TTransportException) {" << '\n'; indent_up(); indent(out) << "logger.error(\"TTransportException writing to internal frame buffer\", e)" - << endl; - indent(out) << "fb.close()" << endl; + << '\n'; + indent(out) << "fb.close()" << '\n'; indent_down(); - indent(out) << "} catch (e: Exception) {" << endl; + indent(out) << "} catch (e: Exception) {" << '\n'; indent_up(); - indent(out) << "logger.error(\"Exception writing to internal frame buffer\", e)" << endl; - indent(out) << "onError(e)" << endl; + indent(out) << "logger.error(\"Exception writing to internal frame buffer\", e)" << '\n'; + indent(out) << "onError(e)" << '\n'; scope_down(out); } scope_down(out); } { - indent(out) << "override fun onError(exception: kotlin.Exception) {" << endl; + indent(out) << "override fun onError(exception: kotlin.Exception) {" << '\n'; indent_up(); if (tfunc->is_oneway()) { indent(out) << "if (exception is org.apache.thrift.transport.TTransportException) {" - << endl; + << '\n'; indent_up(); - indent(out) << "logger.error(\"TTransportException inside handler\", exception)" << endl; - indent(out) << "fb.close()" << endl; + indent(out) << "logger.error(\"TTransportException inside handler\", exception)" << '\n'; + indent(out) << "fb.close()" << '\n'; indent_down(); - indent(out) << "} else {" << endl; + indent(out) << "} else {" << '\n'; indent_up(); - indent(out) << "logger.error(\"Exception inside oneway handler\", exception)" << endl; + indent(out) << "logger.error(\"Exception inside oneway handler\", exception)" << '\n'; scope_down(out); } else { - indent(out) << "val (msgType, msg) = when (exception) {" << endl; + indent(out) << "val (msgType, msg) = when (exception) {" << '\n'; indent_up(); auto xceptions = tfunc->get_xceptions()->get_members(); for (auto xception : xceptions) { - indent(out) << "is " << type_name(xception->get_type()) << " -> {" << endl; + indent(out) << "is " << type_name(xception->get_type()) << " -> {" << '\n'; indent_up(); string result_name = tservice->get_name() + "FunctionResult." + tfunc->get_name() + "_result"; - indent(out) << "val result = " << result_name << "()" << endl; - indent(out) << "result." << xception->get_name() << " = exception" << endl; - indent(out) << "org.apache.thrift.protocol.TMessageType.REPLY to result" << endl; + indent(out) << "val result = " << result_name << "()" << '\n'; + indent(out) << "result." << xception->get_name() << " = exception" << '\n'; + indent(out) << "org.apache.thrift.protocol.TMessageType.REPLY to result" << '\n'; scope_down(out); } - indent(out) << "is org.apache.thrift.transport.TTransportException -> {" << endl; + indent(out) << "is org.apache.thrift.transport.TTransportException -> {" << '\n'; indent_up(); - indent(out) << "logger.error(\"TTransportException inside handler\", exception)" << endl; - indent(out) << "fb.close()" << endl; - indent(out) << "return" << endl; + indent(out) << "logger.error(\"TTransportException inside handler\", exception)" << '\n'; + indent(out) << "fb.close()" << '\n'; + indent(out) << "return" << '\n'; scope_down(out); - indent(out) << "is org.apache.thrift.TApplicationException -> {" << endl; + indent(out) << "is org.apache.thrift.TApplicationException -> {" << '\n'; indent_up(); indent(out) << "logger.error(\"TApplicationException inside handler\", exception)" - << endl; - indent(out) << "org.apache.thrift.protocol.TMessageType.EXCEPTION to exception" << endl; + << '\n'; + indent(out) << "org.apache.thrift.protocol.TMessageType.EXCEPTION to exception" << '\n'; scope_down(out); - indent(out) << "else -> {" << endl; + indent(out) << "else -> {" << '\n'; indent_up(); - indent(out) << "logger.error(\"Exception inside handler\", exception)" << endl; + indent(out) << "logger.error(\"Exception inside handler\", exception)" << '\n'; indent(out) << "org.apache.thrift.protocol.TMessageType.EXCEPTION to " "org.apache.thrift.TApplicationException(org.apache.thrift." "TApplicationException.INTERNAL_ERROR, exception.message)" - << endl; + << '\n'; scope_down(out); scope_down(out); - indent(out) << "try {" << endl; + indent(out) << "try {" << '\n'; indent_up(); - indent(out) << "sendResponse(fb, msg, msgType, seqid)" << endl; + indent(out) << "sendResponse(fb, msg, msgType, seqid)" << '\n'; indent_down(); - indent(out) << "} catch (ex: java.lang.Exception) {" << endl; + indent(out) << "} catch (ex: java.lang.Exception) {" << '\n'; indent_up(); - indent(out) << "logger.error(\"Exception writing to internal frame buffer\", ex)" << endl; - indent(out) << "fb.close()" << endl; + indent(out) << "logger.error(\"Exception writing to internal frame buffer\", ex)" << '\n'; + indent(out) << "fb.close()" << '\n'; scope_down(out); } @@ -1843,7 +1852,7 @@ void t_kotlin_generator::generate_service_result_helpers(t_service* tservice) { generate_docstring_comment(out, "/**\n", " * ", "function result for [" + tservice->get_name() + "]", " */\n"); - indent(out) << "sealed interface " << tservice->get_name() << "FunctionResult {" << endl; + indent(out) << "sealed interface " << tservice->get_name() << "FunctionResult {" << '\n'; indent_up(); for (auto func : tservice->get_functions()) { if (func->is_oneway()) { @@ -1870,12 +1879,12 @@ void t_kotlin_generator::generate_service_args_helpers(t_service* tservice) { out << autogen_comment() << warning_surpressions() << kotlin_package(); generate_docstring_comment(out, "/**\n", " * ", "function arguments for [" + tservice->get_name() + "]", " */\n"); - indent(out) << "sealed interface " << tservice->get_name() << "FunctionArgs {" << endl; + indent(out) << "sealed interface " << tservice->get_name() << "FunctionArgs {" << '\n'; indent_up(); for (auto func : tservice->get_functions()) { t_struct* ts = func->get_arglist(); generate_struct_definition(out, ts, false, tservice->get_name() + "FunctionArgs"); - out << endl; + out << '\n'; } scope_down(out); out.close(); @@ -1979,7 +1988,7 @@ bool t_kotlin_generator::is_enum_map(t_type* ttype) { */ string t_kotlin_generator::kotlin_package() { if (!package_name_.empty()) { - return string("package ") + package_name_ + endl + endl; + return string("package ") + package_name_ + "\n" + "\n"; } return ""; } @@ -1987,8 +1996,7 @@ string t_kotlin_generator::kotlin_package() { string t_kotlin_generator::warning_surpressions() { return "@file:Suppress(\"ClassName\", \"PropertyName\", \"RedundantUnitReturnType\", " "\"NestedLambdaShadowedImplicitParameter\", " - "\"RemoveRedundantQualifierName\")" - + endl; + "\"RemoveRedundantQualifierName\")\n"; } string t_kotlin_generator::constant_name(string name) { diff --git a/compiler/cpp/src/thrift/generate/t_lua_generator.cc b/compiler/cpp/src/thrift/generate/t_lua_generator.cc index 0dc7743f479..f7f8f054e08 100644 --- a/compiler/cpp/src/thrift/generate/t_lua_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_lua_generator.cc @@ -26,8 +26,6 @@ using std::string; using std::vector; using std::map; -static const string endl = "\n"; // avoid ostream << std::endl flushes - /** * LUA code generator. * @@ -190,7 +188,7 @@ void t_lua_generator::init_generator() { f_consts_ << autogen_comment() << lua_includes(); f_types_ << autogen_comment() << lua_includes(); if (gen_requires_) { - f_types_ << endl << "require '" << cur_namespace << "constants'"; + f_types_ << '\n' << "require '" << cur_namespace << "constants'"; } } @@ -207,7 +205,7 @@ void t_lua_generator::generate_typedef(t_typedef* ttypedef) { if (ttypedef->get_type()->get_name().empty()) { return; } - f_types_ << endl << endl << indent() << ttypedef->get_symbolic() << " = " + f_types_ << '\n' << '\n' << indent() << ttypedef->get_symbolic() << " = " << ttypedef->get_type()->get_name(); } @@ -215,7 +213,7 @@ void t_lua_generator::generate_typedef(t_typedef* ttypedef) { * Generates code for an enumerated type (table) */ void t_lua_generator::generate_enum(t_enum* tenum) { - f_types_ << endl << endl << tenum->get_name() << " = {" << endl; + f_types_ << '\n' << '\n' << tenum->get_name() << " = {" << '\n'; vector constants = tenum->get_constants(); vector::iterator c_iter; @@ -227,7 +225,7 @@ void t_lua_generator::generate_enum(t_enum* tenum) { if (c_iter != constants.end()) { f_types_ << ","; } - f_types_ << endl; + f_types_ << '\n'; } f_types_ << "}"; } @@ -240,7 +238,7 @@ void t_lua_generator::generate_const(t_const* tconst) { string name = tconst->get_name(); t_const_value* value = tconst->get_value(); - f_consts_ << endl << endl << name << " = "; + f_consts_ << '\n' << '\n' << name << " = "; f_consts_ << render_const_value(type, value); } @@ -275,13 +273,16 @@ string t_lua_generator::render_const_value(t_type* type, t_const_value* value) { out << value->get_double(); } break; + case t_base_type::TYPE_UUID: + out << "TUUIDfromString(" << value->get_string() << ")"; + break; default: throw "compiler error: no const of base type " + t_base_type::t_base_name(tbase); } } else if (type->is_enum()) { out << value->get_integer(); } else if (type->is_struct() || type->is_xception()) { - out << type->get_name() << " = {" << endl; + out << type->get_name() << " = {" << '\n'; indent_up(); const vector& fields = ((t_struct*)type)->get_members(); @@ -312,7 +313,7 @@ string t_lua_generator::render_const_value(t_type* type, t_const_value* value) { out << "}"; indent_down(); } else if (type->is_map()) { - out << type->get_name() << "{" << endl; + out << type->get_name() << "{" << '\n'; indent_up(); t_type* ktype = ((t_map*)type)->get_key_type(); @@ -327,7 +328,7 @@ string t_lua_generator::render_const_value(t_type* type, t_const_value* value) { if (v_iter != val.end()) { out << ","; } - out << endl; + out << '\n'; } indent_down(); indent(out) << "}"; @@ -338,7 +339,7 @@ string t_lua_generator::render_const_value(t_type* type, t_const_value* value) { } else { etype = ((t_set*)type)->get_elem_type(); } - out << type->get_name() << " = {" << endl; + out << type->get_name() << " = {" << '\n'; const vector& val = value->get_list(); vector::const_iterator v_iter; for (v_iter = val.begin(); v_iter != val.end();) { @@ -351,7 +352,7 @@ string t_lua_generator::render_const_value(t_type* type, t_const_value* value) { } ++v_iter; if (v_iter != val.end()) { - out << "," << endl; + out << "," << '\n'; } } out << "}"; @@ -382,15 +383,15 @@ void t_lua_generator::generate_lua_struct_definition(ostream& out, vector::const_iterator m_iter; const vector& members = tstruct->get_members(); - indent(out) << endl << endl << tstruct->get_name(); + indent(out) << '\n' << '\n' << tstruct->get_name(); if (is_exception) { - out << " = TException:new{" << endl << indent() << " __type = '" << tstruct->get_name() << "'"; + out << " = TException:new{" << '\n' << indent() << " __type = '" << tstruct->get_name() << "'"; if (members.size() > 0) { out << ","; } - out << endl; + out << '\n'; } else { - out << " = __TObject:new{" << endl; + out << " = __TObject:new{" << '\n'; } indent_up(); for (m_iter = members.begin(); m_iter != members.end();) { @@ -398,12 +399,12 @@ void t_lua_generator::generate_lua_struct_definition(ostream& out, out << (*m_iter)->get_name(); ++m_iter; if (m_iter != members.end()) { - out << "," << endl; + out << "," << '\n'; } } indent_down(); indent(out); - out << endl << "}"; + out << '\n' << "}"; generate_lua_struct_reader(out, tstruct); generate_lua_struct_writer(out, tstruct); @@ -417,48 +418,48 @@ void t_lua_generator::generate_lua_struct_reader(ostream& out, t_struct* tstruct vector::const_iterator f_iter; // function - indent(out) << endl << endl << "function " << tstruct->get_name() << ":read(iprot)" << endl; + indent(out) << '\n' << '\n' << "function " << tstruct->get_name() << ":read(iprot)" << '\n'; indent_up(); - indent(out) << "iprot:readStructBegin()" << endl; + indent(out) << "iprot:readStructBegin()" << '\n'; // while: Read in fields - indent(out) << "while true do" << endl; + indent(out) << "while true do" << '\n'; indent_up(); // if: Check what to read - indent(out) << "local fname, ftype, fid = iprot:readFieldBegin()" << endl; - indent(out) << "if ftype == TType.STOP then" << endl; + indent(out) << "local fname, ftype, fid = iprot:readFieldBegin()" << '\n'; + indent(out) << "if ftype == TType.STOP then" << '\n'; indent_up(); - indent(out) << "break" << endl; + indent(out) << "break" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { indent_down(); - indent(out) << "elseif fid == " << (*f_iter)->get_key() << " then" << endl; + indent(out) << "elseif fid == " << (*f_iter)->get_key() << " then" << '\n'; indent_up(); - indent(out) << "if ftype == " << type_to_enum((*f_iter)->get_type()) << " then" << endl; + indent(out) << "if ftype == " << type_to_enum((*f_iter)->get_type()) << " then" << '\n'; indent_up(); // Read field contents generate_deserialize_field(out, *f_iter, false, "self."); indent_down(); - indent(out) << "else" << endl; - indent(out) << " iprot:skip(ftype)" << endl; - indent(out) << "end" << endl; + indent(out) << "else" << '\n'; + indent(out) << " iprot:skip(ftype)" << '\n'; + indent(out) << "end" << '\n'; } // end if indent_down(); - indent(out) << "else" << endl; - indent(out) << " iprot:skip(ftype)" << endl; - indent(out) << "end" << endl; - indent(out) << "iprot:readFieldEnd()" << endl; + indent(out) << "else" << '\n'; + indent(out) << " iprot:skip(ftype)" << '\n'; + indent(out) << "end" << '\n'; + indent(out) << "iprot:readFieldEnd()" << '\n'; // end while indent_down(); - indent(out) << "end" << endl; - indent(out) << "iprot:readStructEnd()" << endl; + indent(out) << "end" << '\n'; + indent(out) << "iprot:readStructEnd()" << '\n'; // end function indent_down(); @@ -474,28 +475,28 @@ void t_lua_generator::generate_lua_struct_writer(ostream& out, t_struct* tstruct vector::const_iterator f_iter; // function - indent(out) << endl << endl << "function " << tstruct->get_name() << ":write(oprot)" << endl; + indent(out) << '\n' << '\n' << "function " << tstruct->get_name() << ":write(oprot)" << '\n'; indent_up(); - indent(out) << "oprot:writeStructBegin('" << tstruct->get_name() << "')" << endl; + indent(out) << "oprot:writeStructBegin('" << tstruct->get_name() << "')" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { // To check element of self whether nil or not. // avoid the value(false) of BOOL is lost. - indent(out) << "if self." << (*f_iter)->get_name() << " ~= nil then" << endl; + indent(out) << "if self." << (*f_iter)->get_name() << " ~= nil then" << '\n'; indent_up(); indent(out) << "oprot:writeFieldBegin('" << (*f_iter)->get_name() << "', " << type_to_enum((*f_iter)->get_type()) << ", " << (*f_iter)->get_key() << ")" - << endl; + << '\n'; // Write field contents generate_serialize_field(out, *f_iter, "self."); - indent(out) << "oprot:writeFieldEnd()" << endl; + indent(out) << "oprot:writeFieldEnd()" << '\n'; indent_down(); - indent(out) << "end" << endl; + indent(out) << "end" << '\n'; } - indent(out) << "oprot:writeFieldStop()" << endl; - indent(out) << "oprot:writeStructEnd()" << endl; + indent(out) << "oprot:writeFieldStop()" << '\n'; + indent(out) << "oprot:writeStructEnd()" << '\n'; // end function indent_down(); @@ -518,15 +519,15 @@ void t_lua_generator::generate_service(t_service* tservice) { // Headers f_service_ << autogen_comment() << lua_includes(); if (gen_requires_) { - f_service_ << endl << "require '" << cur_ns << "ttypes'" << endl; + f_service_ << '\n' << "require '" << cur_ns << "ttypes'" << '\n'; if (tservice->get_extends() != nullptr) { f_service_ << "require '" << get_namespace(tservice->get_extends()->get_program()) - << tservice->get_extends()->get_name() << "'" << endl; + << tservice->get_extends()->get_name() << "'" << '\n'; } } - f_service_ << endl; + f_service_ << '\n'; generate_service_client(f_service_, tservice); generate_service_interface(f_service_, tservice); @@ -544,11 +545,11 @@ void t_lua_generator::generate_service_interface(ostream& out, t_service* tservi // Interface object definition out << classname << " = "; if (extends_s) { - out << extends_s->get_name() << "Iface:new{" << endl; + out << extends_s->get_name() << "Iface:new{" << '\n'; } else { - out << "__TObject:new{" << endl; + out << "__TObject:new{" << '\n'; } - out << " __type = '" << classname << "'" << endl << "}" << endl << endl; + out << " __type = '" << classname << "'" << '\n' << "}" << '\n' << '\n'; } void t_lua_generator::generate_service_client(ostream& out, t_service* tservice) { @@ -562,7 +563,7 @@ void t_lua_generator::generate_service_client(ostream& out, t_service* tservice) } else { out << "__TClient"; } - out << ", {" << endl << " __type = '" << classname << "'" << endl << "})" << endl; + out << ", {" << '\n' << " __type = '" << classname << "'" << '\n' << "})" << '\n'; // Send/Recv functions vector functions = tservice->get_functions(); @@ -572,28 +573,28 @@ void t_lua_generator::generate_service_client(ostream& out, t_service* tservice) string funcname = (*f_iter)->get_name(); // Wrapper function - indent(out) << endl << "function " << classname << ":" << sig << endl; + indent(out) << '\n' << "function " << classname << ":" << sig << '\n'; indent_up(); - indent(out) << "self:send_" << sig << endl << indent(); + indent(out) << "self:send_" << sig << '\n' << indent(); if (!(*f_iter)->is_oneway()) { if (!(*f_iter)->get_returntype()->is_void()) { out << "return "; } - out << "self:recv_" << sig << endl; + out << "self:recv_" << sig << '\n'; } indent_down(); - indent(out) << "end" << endl; + indent(out) << "end" << '\n'; // Send function - indent(out) << endl << "function " << classname << ":send_" << sig << endl; + indent(out) << '\n' << "function " << classname << ":send_" << sig << '\n'; indent_up(); indent(out) << "self.oprot:writeMessageBegin('" << funcname << "', " << ((*f_iter)->is_oneway() ? "TMessageType.ONEWAY" : "TMessageType.CALL") - << ", self._seqid)" << endl; - indent(out) << "local args = " << funcname << "_args:new{}" << endl; + << ", self._seqid)" << '\n'; + indent(out) << "local args = " << funcname << "_args:new{}" << '\n'; // Set the args const vector& args = (*f_iter)->get_arglist()->get_members(); @@ -603,60 +604,60 @@ void t_lua_generator::generate_service_client(ostream& out, t_service* tservice) if ((*fld_iter)->get_value() != nullptr) { // Insert default value for nil arguments t_type* type = get_true_type((*fld_iter)->get_type()); - indent(out) << "if " << argname << " ~= nil then" << endl; + indent(out) << "if " << argname << " ~= nil then" << '\n'; indent_up(); - indent(out) << "args." << argname << " = " << argname << endl; + indent(out) << "args." << argname << " = " << argname << '\n'; indent_down(); - indent(out) << "else" << endl; + indent(out) << "else" << '\n'; indent_up(); - indent(out) << "args." << argname << " = " << render_const_value(type, (*fld_iter)->get_value()) << endl; + indent(out) << "args." << argname << " = " << render_const_value(type, (*fld_iter)->get_value()) << '\n'; indent_down(); - indent(out) << "end" << endl; + indent(out) << "end" << '\n'; } else { - indent(out) << "args." << argname << " = " << argname << endl; + indent(out) << "args." << argname << " = " << argname << '\n'; } } - indent(out) << "args:write(self.oprot)" << endl; - indent(out) << "self.oprot:writeMessageEnd()" << endl; - indent(out) << "self.oprot.trans:flush()" << endl; + indent(out) << "args:write(self.oprot)" << '\n'; + indent(out) << "self.oprot:writeMessageEnd()" << '\n'; + indent(out) << "self.oprot.trans:flush()" << '\n'; indent_down(); - indent(out) << "end" << endl; + indent(out) << "end" << '\n'; // Recv function if (!(*f_iter)->is_oneway()) { - indent(out) << endl << "function " << classname << ":recv_" << sig << endl; + indent(out) << '\n' << "function " << classname << ":recv_" << sig << '\n'; indent_up(); out << indent() << "local fname, mtype, rseqid = self.iprot:" - << "readMessageBegin()" << endl << indent() << "if mtype == TMessageType.EXCEPTION then" - << endl << indent() << " local x = TApplicationException:new{}" << endl << indent() - << " x:read(self.iprot)" << endl << indent() << " self.iprot:readMessageEnd()" << endl - << indent() << " error(x)" << endl << indent() << "end" << endl << indent() - << "local result = " << funcname << "_result:new{}" << endl << indent() - << "result:read(self.iprot)" << endl << indent() << "self.iprot:readMessageEnd()" << endl; + << "readMessageBegin()" << '\n' << indent() << "if mtype == TMessageType.EXCEPTION then" + << '\n' << indent() << " local x = TApplicationException:new{}" << '\n' << indent() + << " x:read(self.iprot)" << '\n' << indent() << " self.iprot:readMessageEnd()" << '\n' + << indent() << " error(x)" << '\n' << indent() << "end" << '\n' << indent() + << "local result = " << funcname << "_result:new{}" << '\n' << indent() + << "result:read(self.iprot)" << '\n' << indent() << "self.iprot:readMessageEnd()" << '\n'; // Return the result if it's not a void function if (!(*f_iter)->get_returntype()->is_void()) { - out << indent() << "if result.success ~= nil then" << endl << indent() << " return result.success" - << endl; + out << indent() << "if result.success ~= nil then" << '\n' << indent() << " return result.success" + << '\n'; // Throw custom exceptions const std::vector& xf = (*f_iter)->get_xceptions()->get_members(); vector::const_iterator x_iter; for (x_iter = xf.begin(); x_iter != xf.end(); ++x_iter) { - out << indent() << "elseif result." << (*x_iter)->get_name() << " then" << endl - << indent() << " error(result." << (*x_iter)->get_name() << ")" << endl; + out << indent() << "elseif result." << (*x_iter)->get_name() << " then" << '\n' + << indent() << " error(result." << (*x_iter)->get_name() << ")" << '\n'; } - out << indent() << "end" << endl << indent() + out << indent() << "end" << '\n' << indent() << "error(TApplicationException:new{errorCode = " - << "TApplicationException.MISSING_RESULT})" << endl; + << "TApplicationException.MISSING_RESULT})" << '\n'; } indent_down(); - indent(out) << "end" << endl; + indent(out) << "end" << '\n'; } } } @@ -666,40 +667,40 @@ void t_lua_generator::generate_service_processor(ostream& out, t_service* tservi t_service* extends_s = tservice->get_extends(); // Define processor table - out << endl << classname << " = __TObject.new("; + out << '\n' << classname << " = __TObject.new("; if (extends_s != nullptr) { - out << extends_s->get_name() << "Processor" << endl; + out << extends_s->get_name() << "Processor" << '\n'; } else { - out << "__TProcessor" << endl; + out << "__TProcessor" << '\n'; } - out << ", {" << endl << " __type = '" << classname << "'" << endl << "})" << endl; + out << ", {" << '\n' << " __type = '" << classname << "'" << '\n' << "})" << '\n'; // Process function - indent(out) << endl << "function " << classname << ":process(iprot, oprot, server_ctx)" << endl; + indent(out) << '\n' << "function " << classname << ":process(iprot, oprot, server_ctx)" << '\n'; indent_up(); - indent(out) << "local name, mtype, seqid = iprot:readMessageBegin()" << endl; - indent(out) << "local func_name = 'process_' .. name" << endl; - indent(out) << "if not self[func_name] or ttype(self[func_name]) ~= 'function' then" << endl; + indent(out) << "local name, mtype, seqid = iprot:readMessageBegin()" << '\n'; + indent(out) << "local func_name = 'process_' .. name" << '\n'; + indent(out) << "if not self[func_name] or ttype(self[func_name]) ~= 'function' then" << '\n'; indent_up(); indent(out) << "if oprot ~= nil then"; indent_up(); - out << endl << indent() << "iprot:skip(TType.STRUCT)" << endl << indent() - << "iprot:readMessageEnd()" << endl << indent() << "x = TApplicationException:new{" << endl - << indent() << " errorCode = TApplicationException.UNKNOWN_METHOD" << endl << indent() << "}" - << endl << indent() << "oprot:writeMessageBegin(name, TMessageType.EXCEPTION, " - << "seqid)" << endl << indent() << "x:write(oprot)" << endl << indent() - << "oprot:writeMessageEnd()" << endl << indent() << "oprot.trans:flush()" << endl; + out << '\n' << indent() << "iprot:skip(TType.STRUCT)" << '\n' << indent() + << "iprot:readMessageEnd()" << '\n' << indent() << "x = TApplicationException:new{" << '\n' + << indent() << " errorCode = TApplicationException.UNKNOWN_METHOD" << '\n' << indent() << "}" + << '\n' << indent() << "oprot:writeMessageBegin(name, TMessageType.EXCEPTION, " + << "seqid)" << '\n' << indent() << "x:write(oprot)" << '\n' << indent() + << "oprot:writeMessageEnd()" << '\n' << indent() << "oprot.trans:flush()" << '\n'; indent_down(); - out << indent() << "end" << endl << indent() - << "return false, 'Unknown function '..name" << endl; + out << indent() << "end" << '\n' << indent() + << "return false, 'Unknown function '..name" << '\n'; indent_down(); - indent(out) << "else" << endl << indent() - << " return self[func_name](self, seqid, iprot, oprot, server_ctx)" << endl << indent() - << "end" << endl; + indent(out) << "else" << '\n' << indent() + << " return self[func_name](self, seqid, iprot, oprot, server_ctx)" << '\n' << indent() + << "end" << '\n'; indent_down(); - indent(out) << "end" << endl; + indent(out) << "end" << '\n'; // Generate the process subfunctions vector functions = tservice->get_functions(); @@ -717,18 +718,20 @@ void t_lua_generator::generate_process_function(ostream& out, string resultname = tfunction->get_name() + "_result"; string fn_name = tfunction->get_name(); - indent(out) << endl << "function " << classname << ":process_" << fn_name - << "(seqid, iprot, oprot, server_ctx)" << endl; + indent(out) << '\n' << "function " << classname << ":process_" << fn_name + << "(seqid, iprot, oprot, server_ctx)" << '\n'; indent_up(); // Read the request - out << indent() << "local args = " << argsname << ":new{}" << endl << indent() - << "local reply_type = TMessageType.REPLY" << endl << indent() << "args:read(iprot)" << endl - << indent() << "iprot:readMessageEnd()" << endl; + out << indent() << "local args = " << argsname << ":new{}" << '\n' << indent() + << "local reply_type = TMessageType.REPLY" << '\n' << indent() << "args:read(iprot)" << '\n' + << indent() << "iprot:readMessageEnd()" << '\n'; if (!tfunction->is_oneway()) { out << indent() << "local result = " << resultname - << ":new{}" << endl; + << ":new{}" << '\n'; + } else { + out << indent() << "oprot.trans:flushOneway()" << '\n'; } out << indent() << "local status, res = pcall(self.handler." << fn_name @@ -738,13 +741,13 @@ void t_lua_generator::generate_process_function(ostream& out, if (args->get_members().size() > 0) { out << ", " << argument_list(args, "args."); } - out << ")" << endl; + out << ")" << '\n'; if (!tfunction->is_oneway()) { // Check for errors - out << indent() << "if not status then" << endl << indent() - << " reply_type = TMessageType.EXCEPTION" << endl << indent() - << " result = TApplicationException:new{message = res}" << endl; + out << indent() << "if not status then" << '\n' << indent() + << " reply_type = TMessageType.EXCEPTION" << '\n' << indent() + << " result = TApplicationException:new{message = res}" << '\n'; // Handle custom exceptions const std::vector& xf = tfunction->get_xceptions()->get_members(); @@ -752,19 +755,19 @@ void t_lua_generator::generate_process_function(ostream& out, vector::const_iterator x_iter; for (x_iter = xf.begin(); x_iter != xf.end(); ++x_iter) { out << indent() << "elseif ttype(res) == '" << (*x_iter)->get_type()->get_name() << "' then" - << endl << indent() << " result." << (*x_iter)->get_name() << " = res" << endl; + << '\n' << indent() << " result." << (*x_iter)->get_name() << " = res" << '\n'; } } // Set the result and write the reply - out << indent() << "else" << endl << indent() << " result.success = res" << endl << indent() - << "end" << endl << indent() << "oprot:writeMessageBegin('" << fn_name << "', reply_type, " - << "seqid)" << endl << indent() << "result:write(oprot)" << endl << indent() - << "oprot:writeMessageEnd()" << endl << indent() << "oprot.trans:flush()" << endl; + out << indent() << "else" << '\n' << indent() << " result.success = res" << '\n' << indent() + << "end" << '\n' << indent() << "oprot:writeMessageBegin('" << fn_name << "', reply_type, " + << "seqid)" << '\n' << indent() << "result:write(oprot)" << '\n' << indent() + << "oprot:writeMessageEnd()" << '\n' << indent() << "oprot.trans:flush()" << '\n'; } - out << indent() << "return status, res" << endl; + out << indent() << "return status, res" << '\n'; indent_down(); - indent(out) << "end" << endl; + indent(out) << "end" << '\n'; } // Service helpers @@ -772,7 +775,7 @@ void t_lua_generator::generate_service_helpers(ostream& out, t_service* tservice vector functions = tservice->get_functions(); vector::iterator f_iter; - out << endl << "-- HELPER FUNCTIONS AND STRUCTURES"; + out << '\n' << "-- HELPER FUNCTIONS AND STRUCTURES"; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { t_struct* ts = (*f_iter)->get_arglist(); generate_lua_struct_definition(out, ts, false); @@ -847,13 +850,16 @@ void t_lua_generator::generate_deserialize_field(ostream& out, case t_base_type::TYPE_DOUBLE: out << "readDouble()"; break; + case t_base_type::TYPE_UUID: + out << "readUuid()"; + break; default: throw "compiler error: no PHP name for base type " + t_base_type::t_base_name(tbase); } } else if (type->is_enum()) { out << "readI32()"; } - out << endl; + out << '\n'; } else { printf("DO NOT KNOW HOW TO DESERIALIZE FIELD '%s' TYPE '%s'\n", @@ -867,7 +873,7 @@ void t_lua_generator::generate_deserialize_struct(ostream& out, bool local, string prefix) { indent(out) << (local ? "local " : "") << prefix << " = " << tstruct->get_name() << ":new{}" - << endl << indent() << prefix << ":read(iprot)" << endl; + << '\n' << indent() << prefix << ":read(iprot)" << '\n'; } void t_lua_generator::generate_deserialize_container(ostream& out, @@ -885,18 +891,18 @@ void t_lua_generator::generate_deserialize_container(ostream& out, t_field fetype(g_type_i8, etype); // Declare variables, read header - indent(out) << (local ? "local " : "") << prefix << " = {}" << endl; + indent(out) << (local ? "local " : "") << prefix << " = {}" << '\n'; if (ttype->is_map()) { indent(out) << "local " << ktype << ", " << vtype << ", " << size << " = iprot:readMapBegin() " - << endl; + << '\n'; } else if (ttype->is_set()) { - indent(out) << "local " << etype << ", " << size << " = iprot:readSetBegin()" << endl; + indent(out) << "local " << etype << ", " << size << " = iprot:readSetBegin()" << '\n'; } else if (ttype->is_list()) { - indent(out) << "local " << etype << ", " << size << " = iprot:readListBegin()" << endl; + indent(out) << "local " << etype << ", " << size << " = iprot:readListBegin()" << '\n'; } // Deserialize - indent(out) << "for _i=1," << size << " do" << endl; + indent(out) << "for _i=1," << size << " do" << '\n'; indent_up(); if (ttype->is_map()) { @@ -908,15 +914,15 @@ void t_lua_generator::generate_deserialize_container(ostream& out, } indent_down(); - indent(out) << "end" << endl; + indent(out) << "end" << '\n'; // Read container end if (ttype->is_map()) { - indent(out) << "iprot:readMapEnd()" << endl; + indent(out) << "iprot:readMapEnd()" << '\n'; } else if (ttype->is_set()) { - indent(out) << "iprot:readSetEnd()" << endl; + indent(out) << "iprot:readSetEnd()" << '\n'; } else if (ttype->is_list()) { - indent(out) << "iprot:readListEnd()" << endl; + indent(out) << "iprot:readListEnd()" << '\n'; } } @@ -930,7 +936,7 @@ void t_lua_generator::generate_deserialize_map_element(ostream& out, t_map* tmap generate_deserialize_field(out, &fkey, true); generate_deserialize_field(out, &fval, true); - indent(out) << prefix << "[" << key << "] = " << val << endl; + indent(out) << prefix << "[" << key << "] = " << val << '\n'; } void t_lua_generator::generate_deserialize_set_element(ostream& out, t_set* tset, string prefix) { @@ -940,7 +946,7 @@ void t_lua_generator::generate_deserialize_set_element(ostream& out, t_set* tset generate_deserialize_field(out, &felem, true); - indent(out) << prefix << "[" << elem << "] = " << elem << endl; + indent(out) << prefix << "[" << elem << "] = " << elem << '\n'; } void t_lua_generator::generate_deserialize_list_element(ostream& out, @@ -953,7 +959,7 @@ void t_lua_generator::generate_deserialize_list_element(ostream& out, generate_deserialize_field(out, &felem, true); - indent(out) << "table.insert(" << prefix << ", " << elem << ")" << endl; + indent(out) << "table.insert(" << prefix << ", " << elem << ")" << '\n'; } /** @@ -1002,13 +1008,16 @@ void t_lua_generator::generate_serialize_field(ostream& out, t_field* tfield, st case t_base_type::TYPE_DOUBLE: out << "writeDouble(" << name << ")"; break; + case t_base_type::TYPE_UUID: + out << "writeUuid(" << name << ")"; + break; default: throw "compiler error: no PHP name for base type " + t_base_type::t_base_name(tbase); } } else if (type->is_enum()) { out << "writeI32(" << name << ")"; } - out << endl; + out << '\n'; } else { printf("DO NOT KNOW HOW TO SERIALIZE FIELD '%s' TYPE '%s'\n", name.c_str(), @@ -1018,7 +1027,7 @@ void t_lua_generator::generate_serialize_field(ostream& out, t_field* tfield, st void t_lua_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix) { (void)tstruct; - indent(out) << prefix << ":write(oprot)" << endl; + indent(out) << prefix << ":write(oprot)" << '\n'; } void t_lua_generator::generate_serialize_container(ostream& out, t_type* ttype, string prefix) { @@ -1026,48 +1035,48 @@ void t_lua_generator::generate_serialize_container(ostream& out, t_type* ttype, if (ttype->is_map()) { indent(out) << "oprot:writeMapBegin(" << type_to_enum(((t_map*)ttype)->get_key_type()) << ", " << type_to_enum(((t_map*)ttype)->get_val_type()) << ", " - << "ttable_size(" << prefix << "))" << endl; + << "ttable_size(" << prefix << "))" << '\n'; } else if (ttype->is_set()) { indent(out) << "oprot:writeSetBegin(" << type_to_enum(((t_set*)ttype)->get_elem_type()) << ", " - << "ttable_size(" << prefix << "))" << endl; + << "ttable_size(" << prefix << "))" << '\n'; } else if (ttype->is_list()) { indent(out) << "oprot:writeListBegin(" << type_to_enum(((t_list*)ttype)->get_elem_type()) << ", " - << "#" << prefix << ")" << endl; + << "#" << prefix << ")" << '\n'; } // Serialize if (ttype->is_map()) { string kiter = tmp("kiter"); string viter = tmp("viter"); - indent(out) << "for " << kiter << "," << viter << " in pairs(" << prefix << ") do" << endl; + indent(out) << "for " << kiter << "," << viter << " in pairs(" << prefix << ") do" << '\n'; indent_up(); generate_serialize_map_element(out, (t_map*)ttype, kiter, viter); indent_down(); - indent(out) << "end" << endl; + indent(out) << "end" << '\n'; } else if (ttype->is_set()) { string iter = tmp("iter"); - indent(out) << "for " << iter << ",_ in pairs(" << prefix << ") do" << endl; + indent(out) << "for " << iter << ",_ in pairs(" << prefix << ") do" << '\n'; indent_up(); generate_serialize_set_element(out, (t_set*)ttype, iter); indent_down(); - indent(out) << "end" << endl; + indent(out) << "end" << '\n'; } else if (ttype->is_list()) { string iter = tmp("iter"); - indent(out) << "for _," << iter << " in ipairs(" << prefix << ") do" << endl; + indent(out) << "for _," << iter << " in ipairs(" << prefix << ") do" << '\n'; indent_up(); generate_serialize_list_element(out, (t_list*)ttype, iter); indent_down(); - indent(out) << "end" << endl; + indent(out) << "end" << '\n'; } // Finish writing if (ttype->is_map()) { - indent(out) << "oprot:writeMapEnd()" << endl; + indent(out) << "oprot:writeMapEnd()" << '\n'; } else if (ttype->is_set()) { - indent(out) << "oprot:writeSetEnd()" << endl; + indent(out) << "oprot:writeSetEnd()" << '\n'; } else if (ttype->is_list()) { - indent(out) << "oprot:writeListEnd()" << endl; + indent(out) << "oprot:writeListEnd()" << '\n'; } } @@ -1153,6 +1162,8 @@ string t_lua_generator::type_to_enum(t_type* type) { return "TType.I64"; case t_base_type::TYPE_DOUBLE: return "TType.DOUBLE"; + case t_base_type::TYPE_UUID: + return "TType.UUID"; default: throw "compiler error: unhandled type"; } diff --git a/compiler/cpp/src/thrift/generate/t_markdown_generator.cc b/compiler/cpp/src/thrift/generate/t_markdown_generator.cc index 76fe98b4e53..fbcaccca02e 100644 --- a/compiler/cpp/src/thrift/generate/t_markdown_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_markdown_generator.cc @@ -38,9 +38,6 @@ using std::string; using std::stringstream; using std::vector; -static const char endl = '\n'; // avoid ostream << std::endl flushes - - /** * MARKDOWN code generator * @@ -55,7 +52,7 @@ enum input_type { INPUT_UNKNOWN, INPUT_UTF8, INPUT_PLAIN }; const std::map& parsed_options, const std::string& option_string) : t_generator(program) { - + (void)option_string; std::map::const_iterator iter; @@ -128,14 +125,14 @@ enum input_type { INPUT_UNKNOWN, INPUT_UTF8, INPUT_PLAIN }; /** - * string to markdown-id link reference + * string to markdown-id link reference */ std::string t_markdown_generator::str_to_id(const std::string& s) { std::string id; for(auto chr=s.begin();chr<=s.end(); ++chr) { if(*chr == '.' || *chr == 0) continue; - id += tolower(*chr); + id += tolower(*chr); } return id; } @@ -144,10 +141,10 @@ std::string t_markdown_generator::str_to_id(const std::string& s) { * Emits the Table of Contents links at the top of the module's page */ void t_markdown_generator::generate_program_toc() { - f_out_ << "| Module | Services & Functions | Data types | Constants |" << endl - << "| --- | --- | --- | --- |" << endl; + f_out_ << "| Module | Services & Functions | Data types | Constants |" << '\n' + << "| --- | --- | --- | --- |" << '\n'; generate_program_toc_row(program_); - f_out_ << endl; + f_out_ << '\n'; } /** @@ -191,24 +188,24 @@ void t_markdown_generator::generate_program_toc_row(t_program* tprog) { fill = &filling.back(); } string name = get_service_name(*sv_iter); - (*fill)[1] = "[" + name + "](" - + make_file_link(fname) + (*fill)[1] = "[" + name + "](" + + make_file_link(fname) + "#service-" + str_to_id(name) + ")"; - + vector functions = (*sv_iter)->get_functions(); vector::iterator fn_iter; - for (fn_iter = functions.begin(); fn_iter != functions.end(); ++fn_iter) { - string fn_name = (*fn_iter)->get_name(); + for (fn_iter = functions.begin(); fn_iter != functions.end(); ++fn_iter) { + string fn_name = (*fn_iter)->get_name(); filling.emplace_back(); fill = &filling.back(); - (*fill)[1] = " [ • " + fn_name + "](" - + make_file_link(fname) + (*fill)[1] = " [ • " + fn_name + "](" + + make_file_link(fname) + "#function-" + str_to_id(name + fn_name) + ")"; } } } - - // Data Types Column + + // Data Types Column auto it_fill = filling.begin(); if (!tprog->get_enums().empty()) { @@ -224,8 +221,8 @@ void t_markdown_generator::generate_program_toc_row(t_program* tprog) { ++it_fill; } string name = (*en_iter)->get_name(); - (*fill)[2] = "[" + name + "](" - + make_file_link(fname) + (*fill)[2] = "[" + name + "](" + + make_file_link(fname) + "#enumeration-" + str_to_id(name) + ")"; } } @@ -242,15 +239,15 @@ void t_markdown_generator::generate_program_toc_row(t_program* tprog) { ++it_fill; } string name = (*td_iter)->get_symbolic(); - (*fill)[2] = "[" + name + "](" - + make_file_link(fname) + (*fill)[2] = "[" + name + "](" + + make_file_link(fname) + "#typedef-" + str_to_id(name) + ")"; } } if (!tprog->get_objects().empty()) { vector objects = tprog->get_objects(); vector::iterator o_iter; - for (o_iter = objects.begin(); o_iter != objects.end(); ++o_iter) { + for (o_iter = objects.begin(); o_iter != objects.end(); ++o_iter) { if(it_fill == filling.end()) { filling.emplace_back(); fill = &filling.back(); @@ -261,7 +258,7 @@ void t_markdown_generator::generate_program_toc_row(t_program* tprog) { } string name = (*o_iter)->get_name(); (*fill)[2] = "[" + name + "](" + make_file_link(fname); - + if ((*o_iter)->is_xception()) { (*fill)[2] += "#exception-"; } else if ((*o_iter)->is_struct() && (*o_iter)->is_union()) { @@ -270,11 +267,11 @@ void t_markdown_generator::generate_program_toc_row(t_program* tprog) { (*fill)[2] += "#struct-"; } (*fill)[2] += str_to_id(name) + ")"; - + } } - - // Constants Column + + // Constants Column it_fill = filling.begin(); if (!tprog->get_consts().empty()) { @@ -291,19 +288,19 @@ void t_markdown_generator::generate_program_toc_row(t_program* tprog) { ++it_fill; } string name = (*con_iter)->get_name(); - (*fill)[3] = "[" + name + "](" - + make_file_link(fname) + (*fill)[3] = "[" + name + "](" + + make_file_link(fname) + "#constant-" + str_to_id(name) + ")"; } - + } - + for(auto& fill : filling) { for(auto& c : fill) - f_out_ << '|' << c; - f_out_ << '|' << endl; + f_out_ << '|' << c; + f_out_ << '|' << '\n'; } - f_out_ << endl; + f_out_ << '\n'; } /** @@ -318,24 +315,24 @@ void t_markdown_generator::generate_program() { current_file_ = make_file_name(pname); string fname = get_out_dir() + current_file_; f_out_.open(fname.c_str()); - f_out_ << "# Thrift module: " << pname << endl << endl; + f_out_ << "# Thrift module: " << pname << '\n' << '\n'; print_doc(program_); - f_out_ << endl << endl; + f_out_ << '\n' << '\n'; generate_program_toc(); if (!program_->get_consts().empty()) { - f_out_ << "***" << endl << "## Constants" << endl << endl; + f_out_ << "***" << '\n' << "## Constants" << '\n' << '\n'; vector consts = program_->get_consts(); - f_out_ << "|Constant|Type|Value||" << endl - << "|---|---|---|---|" << endl; + f_out_ << "|Constant|Type|Value||" << '\n' + << "|---|---|---|---|" << '\n'; generate_consts(consts); - f_out_ << endl; + f_out_ << '\n'; } if (!program_->get_enums().empty()) { - f_out_ << "***" << endl << "## Enumerations" << endl << endl; + f_out_ << "***" << '\n' << "## Enumerations" << '\n' << '\n'; // Generate enums vector enums = program_->get_enums(); vector::iterator en_iter; @@ -345,7 +342,7 @@ void t_markdown_generator::generate_program() { } if (!program_->get_typedefs().empty()) { - f_out_ << "***" << endl << "## Type declarations" << endl << endl; + f_out_ << "***" << '\n' << "## Type declarations" << '\n' << '\n'; // Generate typedefs vector typedefs = program_->get_typedefs(); vector::iterator td_iter; @@ -355,7 +352,7 @@ void t_markdown_generator::generate_program() { } if (!program_->get_objects().empty()) { - f_out_ << "***" << endl << "## Data structures" << endl << endl; + f_out_ << "***" << '\n' << "## Data structures" << '\n' << '\n'; // Generate structs and exceptions in declared order vector objects = program_->get_objects(); vector::iterator o_iter; @@ -369,7 +366,7 @@ void t_markdown_generator::generate_program() { } if (!program_->get_services().empty()) { - f_out_ << "***" << endl << "## Services" << endl << endl; + f_out_ << "***" << '\n' << "## Services" << '\n' << '\n'; // Generate services vector services = program_->get_services(); vector::iterator sv_iter; @@ -379,7 +376,7 @@ void t_markdown_generator::generate_program() { } } - f_out_ << endl; + f_out_ << '\n'; f_out_.close(); generate_index(); @@ -392,15 +389,15 @@ void t_markdown_generator::generate_index() { current_file_ = make_file_name("index"); string index_fname = get_out_dir() + current_file_; f_out_.open(index_fname.c_str()); - - f_out_ << "# Thrift declarations" << endl; - f_out_ << "| Module | Services & Functions | Data types | Constants |" - << endl - << "| --- | --- | --- | --- |" - << endl; + + f_out_ << "# Thrift declarations" << '\n'; + f_out_ << "| Module | Services & Functions | Data types | Constants |" + << '\n' + << "| --- | --- | --- | --- |" + << '\n'; vector programs; generate_program_toc_rows(program_, programs); - f_out_ << endl; + f_out_ << '\n'; f_out_.close(); } @@ -716,13 +713,13 @@ int t_markdown_generator::print_type(t_type* ttype) { f_out_ << ">"; } } else if (ttype->is_base_type()) { - f_out_ << "```" << (ttype->is_binary() ? "binary" : ttype->get_name()) + f_out_ << "```" << (ttype->is_binary() ? "binary" : ttype->get_name()) << "```"; len = ttype->get_name().size(); } else { string prog_name = ttype->get_program()->get_name(); string type_name = ttype->get_name(); - f_out_ << "[```" << type_name << "```](" + f_out_ << "[```" << type_name << "```](" << make_file_link(make_file_name(prog_name)) << "#"; if (ttype->is_typedef()) { f_out_ << "typedef-"; @@ -740,7 +737,7 @@ int t_markdown_generator::print_type(t_type* ttype) { } len = type_name.size(); if (ttype->get_program() != program_) { - f_out_ << str_to_id(prog_name); + f_out_ << str_to_id(prog_name); len += prog_name.size() + 1; } f_out_ << str_to_id(type_name) << ')'; @@ -757,8 +754,8 @@ void t_markdown_generator::print_const_value(t_type* type, t_const_value* tvalue if (tvalue->get_type() == t_const_value::CV_IDENTIFIER) { string fname = make_file_name(program_->get_name()); string name = escape_html(tvalue->get_identifier()); - f_out_ << "[```" << name << "```](" - + make_file_link(fname) + f_out_ << "[```" << name << "```](" + + make_file_link(fname) + "#constant-" + str_to_id(name) + ")"; return; } @@ -773,7 +770,7 @@ void t_markdown_generator::print_const_value(t_type* type, t_const_value* tvalue t_base_type::t_base tbase = ((t_base_type*)truetype)->get_base(); f_out_ << "```"; switch (tbase) { - case t_base_type::TYPE_STRING: + case t_base_type::TYPE_STRING: f_out_ << escape_html(get_escaped_string(tvalue)); break; case t_base_type::TYPE_BOOL: @@ -893,17 +890,17 @@ void t_markdown_generator::print_fn_args_doc(t_function* tfunction) { } if (has_docs) { arg_iter = args.begin(); - f_out_ << endl << "* parameters:" << endl; + f_out_ << '\n' << "* parameters:" << '\n'; for (int n = 1; arg_iter != args.end(); ++arg_iter, ++n ) { f_out_ << n << ". " << (*arg_iter)->get_name(); f_out_ << " - " << escape_html((*arg_iter)->get_doc()); - f_out_ << endl; + f_out_ << '\n'; } - f_out_ << endl; + f_out_ << '\n'; } } - if(!has_docs) - f_out_ << endl; + if(!has_docs) + f_out_ << '\n'; has_docs = false; vector excepts = tfunction->get_xceptions()->get_members(); @@ -917,14 +914,14 @@ void t_markdown_generator::print_fn_args_doc(t_function* tfunction) { } if (has_docs) { ex_iter = excepts.begin(); - f_out_ << "* exceptions:" << endl; + f_out_ << "* exceptions:" << '\n'; for (; ex_iter != excepts.end(); ex_iter++) { f_out_ << " * " << (*ex_iter)->get_type()->get_name(); f_out_ << " - "; f_out_ << escape_html((*ex_iter)->get_doc()); - f_out_ << endl; + f_out_ << '\n'; } - f_out_ << endl; + f_out_ << '\n'; } } } @@ -936,13 +933,13 @@ void t_markdown_generator::print_fn_args_doc(t_function* tfunction) { */ void t_markdown_generator::generate_typedef(t_typedef* ttypedef) { string name = ttypedef->get_name(); - f_out_ << "### Typedef: " << name << endl; + f_out_ << "### Typedef: " << name << '\n'; print_doc(ttypedef); - f_out_ << endl << endl; + f_out_ << '\n' << '\n'; f_out_ << "_Base type_: **"; print_type(ttypedef->get_type()); - f_out_ << "**" << endl << endl; - f_out_ << endl; + f_out_ << "**" << '\n' << '\n'; + f_out_ << '\n'; } /** @@ -952,10 +949,10 @@ void t_markdown_generator::generate_typedef(t_typedef* ttypedef) { */ void t_markdown_generator::generate_enum(t_enum* tenum) { string name = tenum->get_name(); - f_out_ << "### Enumeration: " << name << endl; + f_out_ << "### Enumeration: " << name << '\n'; print_doc(tenum); - f_out_ << endl << endl << "|Name|Value|Description|" << endl - << "|---|---|---|" << endl; + f_out_ << '\n' << '\n' << "|Name|Value|Description|" << '\n' + << "|---|---|---|" << '\n'; vector values = tenum->get_constants(); vector::iterator val_iter; for (val_iter = values.begin(); val_iter != values.end(); ++val_iter) { @@ -965,9 +962,9 @@ void t_markdown_generator::generate_enum(t_enum* tenum) { f_out_ << (*val_iter)->get_value(); f_out_ << "```|"; print_doc((*val_iter)); - f_out_ << "|" << endl; + f_out_ << "|" << '\n'; } - f_out_ << endl; + f_out_ << '\n'; } /** @@ -984,7 +981,7 @@ void t_markdown_generator::generate_const(t_const* tconst) { if (tconst->has_doc()) { print_doc(tconst); } - f_out_ << '|' << endl; + f_out_ << '|' << '\n'; } /** @@ -1002,14 +999,14 @@ void t_markdown_generator::generate_struct(t_struct* tstruct) { } else { f_out_ << "Struct: "; } - f_out_ << name << endl; + f_out_ << name << '\n'; print_doc(tstruct); - f_out_ << endl << endl; + f_out_ << '\n' << '\n'; vector members = tstruct->get_members(); vector::iterator mem_iter = members.begin(); f_out_ << "| Key | Field | Type | Description | Requiredness " - "| Default value |" << endl - << "| --- | --- | --- | --- | --- | --- |" << endl; + "| Default value |" << '\n' + << "| --- | --- | --- | --- | --- | --- |" << '\n'; for (; mem_iter != members.end(); mem_iter++) { f_out_ << '|' << (*mem_iter)->get_key(); f_out_ << '|' << (*mem_iter)->get_name(); @@ -1030,9 +1027,9 @@ void t_markdown_generator::generate_struct(t_struct* tstruct) { print_const_value((*mem_iter)->get_type(), default_val); f_out_ << "```"; } - f_out_ << '|' << endl; + f_out_ << '|' << '\n'; } - f_out_ << endl; + f_out_ << '\n'; } /** @@ -1050,32 +1047,32 @@ void t_markdown_generator::generate_xception(t_struct* txception) { * @param tservice The service definition */ void t_markdown_generator::generate_service(t_service* tservice) { - f_out_ << "### Service: " << service_name_ << endl; + f_out_ << "### Service: " << service_name_ << '\n'; if (tservice->get_extends()) { f_out_ << "**extends ** _"; print_type(tservice->get_extends()); - f_out_ << "_" << endl; + f_out_ << "_" << '\n'; } print_doc(tservice); - f_out_ << endl; + f_out_ << '\n'; vector functions = tservice->get_functions(); vector::iterator fn_iter = functions.begin(); for (; fn_iter != functions.end(); fn_iter++) { string fn_name = (*fn_iter)->get_name(); - f_out_ << "#### Function: " << service_name_ << "." << fn_name << endl; + f_out_ << "#### Function: " << service_name_ << "." << fn_name << '\n'; print_doc(*fn_iter); - f_out_ << endl << endl; + f_out_ << '\n' << '\n'; print_type((*fn_iter)->get_returntype()); bool first = true; - f_out_ << endl << " _" << fn_name << "_("; + f_out_ << '\n' << " _" << fn_name << "_("; vector args = (*fn_iter)->get_arglist()->get_members(); vector::iterator arg_iter = args.begin(); for (; arg_iter != args.end(); arg_iter++) { if (!first) { - f_out_ << "," << endl; + f_out_ << "," << '\n'; } first = false; print_type((*arg_iter)->get_type()); @@ -1085,7 +1082,7 @@ void t_markdown_generator::generate_service(t_service* tservice) { print_const_value((*arg_iter)->get_type(), (*arg_iter)->get_value()); } } - f_out_ << ")" << endl; + f_out_ << ")" << '\n'; first = true; vector excepts = (*fn_iter)->get_xceptions()->get_members(); vector::iterator ex_iter = excepts.begin(); @@ -1098,10 +1095,10 @@ void t_markdown_generator::generate_service(t_service* tservice) { first = false; print_type((*ex_iter)->get_type()); } - f_out_ << endl; + f_out_ << '\n'; } print_fn_args_doc(*fn_iter); - f_out_ << endl; + f_out_ << '\n'; } } diff --git a/compiler/cpp/src/thrift/generate/t_netstd_generator.cc b/compiler/cpp/src/thrift/generate/t_netstd_generator.cc index 1a27c0c3b2f..c35ce563907 100644 --- a/compiler/cpp/src/thrift/generate/t_netstd_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_netstd_generator.cc @@ -82,8 +82,8 @@ t_netstd_generator::t_netstd_generator(t_program* program, const mapfirst.compare("no_deepcopy") == 0) { suppress_deepcopy = true; } - else if (iter->first.compare("net6") == 0) { - target_net_version = 6; + else if (iter->first.compare("net9") == 0) { + target_net_version = 9; } else if (iter->first.compare("net8") == 0) { target_net_version = 8; @@ -202,27 +202,133 @@ void t_netstd_generator::reset_indent() { void t_netstd_generator::pragmas_and_directives(ostream& out) { + if( target_net_version >= 9) { + out << "// targeting net 9" << '\n'; + out << "#if( !NET9_0_OR_GREATER)" << '\n'; + } else if( target_net_version >= 8) { + out << "// targeting net 8" << '\n'; + out << "#if( NET9_0_OR_GREATER || !NET8_0_OR_GREATER)" << '\n'; + } else { + out << "// targeting netstandard 2.x" << '\n'; + out << "#if(! NETSTANDARD2_0_OR_GREATER)" << '\n'; + } + out << "#error Unexpected target platform. See 'thrift --help' for details." << '\n'; + out << "#endif" << '\n'; + out << '\n'; + if( target_net_version >= 6) { - out << "// Thrift code generated for net" << target_net_version << endl; - out << "#nullable enable // requires C# 8.0" << endl; + out << "// Thrift code generated for net" << target_net_version << '\n'; + out << "#nullable enable // requires C# 8.0" << '\n'; } // this one must be first - out << "#pragma warning disable IDE0079 // remove unnecessary pragmas" << endl; + out << "#pragma warning disable IDE0079 // remove unnecessary pragmas" << '\n'; - if( target_net_version >= 8) { - out << "#pragma warning disable IDE0290 // use primary CTOR" << endl; - } else { - out << "#pragma warning disable IDE0017 // object init can be simplified" << endl; - out << "#pragma warning disable IDE0028 // collection init can be simplified" << endl; + if( target_net_version >= 9) { + out << "#pragma warning disable IDE0130 // unexpected folder structure" << '\n'; + } + + if( target_net_version < 8) { + out << "#pragma warning disable IDE0017 // object init can be simplified" << '\n'; + out << "#pragma warning disable IDE0028 // collection init can be simplified" << '\n'; + out << "#pragma warning disable IDE0305 // collection init can be simplified" << '\n'; + out << "#pragma warning disable IDE0034 // simplify default expression" << '\n'; + out << "#pragma warning disable IDE0066 // use switch expression" << '\n'; + out << "#pragma warning disable IDE0090 // simplify new expression" << '\n'; + } + + out << "#pragma warning disable IDE0290 // use primary CTOR" << '\n'; + out << "#pragma warning disable IDE1006 // parts of the code use IDL spelling" << '\n'; + out << "#pragma warning disable CA1822 // empty " << DEEP_COPY_METHOD_NAME << "() methods still non-static" << '\n'; + + if( any_deprecations()) { + out << "#pragma warning disable CS0618 // silence our own deprecation warnings" << '\n'; } - out << "#pragma warning disable IDE1006 // parts of the code use IDL spelling" << endl; - out << "#pragma warning disable CA1822 // empty " << DEEP_COPY_METHOD_NAME << "() methods still non-static" << endl; if( target_net_version < 6) { - out << "#pragma warning disable IDE0083 // pattern matching \"that is not SomeType\" requires net5.0 but we still support earlier versions" << endl; + out << "#pragma warning disable IDE0083 // pattern matching \"that is not SomeType\" requires net5.0 but we still support earlier versions" << '\n'; + } + out << '\n'; +} + + +bool t_netstd_generator::any_deprecations() +{ + // enums + vector enums = program_->get_enums(); + vector::iterator en_iter; + for (en_iter = enums.begin(); en_iter != enums.end(); ++en_iter) { + if( is_deprecated((*en_iter)->annotations_)) { + return true; + } + + // enum values + vector evals = (*en_iter)->get_constants(); + vector::iterator ev_iter; + for (ev_iter = evals.begin(); ev_iter != evals.end(); ++ev_iter) { + if( is_deprecated((*ev_iter)->annotations_)) { + return true; + } + } + } + + // typedefs + vector typedefs = program_->get_typedefs(); + vector::iterator td_iter; + for (td_iter = typedefs.begin(); td_iter != typedefs.end(); ++td_iter) { + if( is_deprecated((*td_iter)->annotations_)) { + return true; + } + } + + // structs, exceptions, unions + vector objects = program_->get_objects(); + vector::iterator o_iter; + for (o_iter = objects.begin(); o_iter != objects.end(); ++o_iter) { + if( is_deprecated((*o_iter)->annotations_)) { + return true; + } + + // struct members + const vector& members = (*o_iter)->get_members(); + vector::const_iterator m_iter; + for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { + if( is_deprecated((*m_iter)->annotations_)) { + return true; + } } - out << endl; + } + + /* not yet + // constants + vector consts = program_->get_consts(); + vector::iterator c_iter; + for (c_iter = consts.begin(); c_iter != consts.end(); ++c_iter) { + if( is_deprecated((*c_iter)->annotations_)) { + return true; + } + } + */ + + // services + vector services = program_->get_services(); + vector::iterator sv_iter; + for (sv_iter = services.begin(); sv_iter != services.end(); ++sv_iter) { + if( is_deprecated((*sv_iter)->annotations_)) { + return true; + } + + // service methods + vector functions = (*sv_iter)->get_functions(); + vector::iterator f_iter; + for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { + if( is_deprecated((*f_iter)->annotations_)) { + return true; + } + } + } + + return false; } @@ -230,7 +336,20 @@ void t_netstd_generator::start_netstd_namespace(ostream& out) { if (!namespace_name_.empty()) { - out << "namespace " << namespace_name_ << endl; + std::string normalized; + + const char* delim = "."; + char* str = strdup(namespace_name_.c_str()); + char* next = strtok(str, delim); + while( next != NULL) { + if( normalized.length() > 0) { + normalized += "."; + } + normalized += normalize_name(next,false); + next = strtok(NULL, delim); + } + + out << "namespace " << normalized << '\n'; scope_up(out); } } @@ -261,6 +380,9 @@ string t_netstd_generator::netstd_type_usings() const if (is_wcf_enabled()) { namespaces += "using System.ServiceModel;\n"; + } + if (is_wcf_enabled() || is_serialize_enabled()) + { namespaces += "using System.Runtime.Serialization;\n"; } @@ -309,13 +431,15 @@ void t_netstd_generator::generate_enum(t_enum* tenum) void t_netstd_generator::generate_enum(ostream& out, t_enum* tenum) { reset_indent(); - out << autogen_comment() << endl; + out << autogen_comment(); + out << "using System;" << '\n' << '\n'; // needed for Obsolete() attribute pragmas_and_directives(out); start_netstd_namespace(out); generate_netstd_doc(out, tenum); - out << indent() << "public enum " << type_name(tenum,false) << endl; + generate_deprecation_attribute(out, tenum->annotations_); + out << indent() << "public enum " << type_name(tenum,false) << '\n'; scope_up(out); vector constants = tenum->get_constants(); @@ -325,7 +449,8 @@ void t_netstd_generator::generate_enum(ostream& out, t_enum* tenum) { generate_netstd_doc(out, *c_iter); int value = (*c_iter)->get_value(); - out << indent() << normalize_name((*c_iter)->get_name()) << " = " << value << "," << endl; + generate_deprecation_attribute(out, (*c_iter)->annotations_); + out << indent() << normalize_name((*c_iter)->get_name()) << " = " << value << "," << '\n'; } scope_down(out); @@ -356,12 +481,12 @@ void t_netstd_generator::generate_consts(ostream& out, vector consts) } reset_indent(); - out << autogen_comment() << netstd_type_usings() << endl << endl; + out << autogen_comment() << netstd_type_usings() << '\n' << '\n'; pragmas_and_directives(out); start_netstd_namespace(out); - out << indent() << "public static class " << make_valid_csharp_identifier(program_name_) << "Constants" << endl; + out << indent() << "public static class " << make_valid_csharp_identifier(program_name_) << "Constants" << '\n'; scope_up(out); @@ -416,7 +541,7 @@ void t_netstd_generator::print_const_def_value(ostream& out, string name, t_type 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; + out << indent() << name << "." << prop_name(field) << " = " << val << ";" << '\n'; } cleanup_member_name_mapping(static_cast(type)); @@ -431,7 +556,7 @@ void t_netstd_generator::print_const_def_value(ostream& out, string name, t_type { 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; + out << indent() << name << "[" << key << "]" << " = " << val << ";" << '\n'; } } else if (type->is_list() || type->is_set()) @@ -451,14 +576,14 @@ void t_netstd_generator::print_const_def_value(ostream& out, string name, t_type 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; + out << indent() << name << ".Add(" << val << ");" << '\n'; } } } void t_netstd_generator::print_const_constructor(ostream& out, vector consts) { - out << indent() << "static " << make_valid_csharp_identifier(program_name_).c_str() << "Constants()" << endl; + out << indent() << "static " << make_valid_csharp_identifier(program_name_).c_str() << "Constants()" << '\n'; scope_up(out); vector::iterator c_iter; @@ -494,30 +619,30 @@ bool t_netstd_generator::print_const_value(ostream& out, string name, t_type* ty if (type->is_base_type()) { string v2 = render_const_value(out, name, type, value); - out << name << " = " << v2 << ";" << endl; + out << name << " = " << v2 << ";" << '\n'; need_static_construction = false; } else if (type->is_enum()) { - out << name << " = " << type_name(type) << "." << value->get_identifier_name() << ";" << endl; + out << name << " = " << type_name(type) << "." << value->get_identifier_name() << ";" << '\n'; need_static_construction = false; } else if (type->is_struct() || type->is_xception()) { if(target_net_version >= 6) { - out << name << " = new();" << endl; + out << name << " = new();" << '\n'; } else { - out << name << " = new " << type_name(type) << "();" << endl; + out << name << " = new " << type_name(type) << "();" << '\n'; } } else if (type->is_map() || type->is_list() || type->is_set()) { if(target_net_version >= 8) { - out << name << " = [];" << endl; + out << name << " = [];" << '\n'; } else if(target_net_version >= 6) { - out << name << " = new();" << endl; + out << name << " = new();" << '\n'; } else { - out << name << " = new " << type_name(type) << "();" << endl; + out << name << " = new " << type_name(type) << "();" << '\n'; } } @@ -672,49 +797,53 @@ void t_netstd_generator::generate_extensions(ostream& out, map reset_indent(); out << autogen_comment() << netstd_type_usings() - << "using Thrift.Protocol;" << endl - << endl << endl; + << "using Thrift.Protocol;" << '\n' + << '\n' << '\n'; pragmas_and_directives(out); start_netstd_namespace(out); - out << indent() << "public static class " << make_valid_csharp_identifier(program_name_) << "Extensions" << endl; + out << indent() << "public static class " << make_valid_csharp_identifier(program_name_) << "Extensions" << '\n'; scope_up(out); bool needs_typecast = false; std::map::const_iterator iter; for( iter = types.begin(); iter != types.end(); ++iter) { - out << indent() << "public static bool Equals(this " << iter->first << " instance, object that)" << endl; + out << indent() << "public static bool Equals(this " << iter->first << " instance, object that)" << '\n'; scope_up(out); if( target_net_version >= 6) { - out << indent() << "if (that is not " << iter->first << " other) return false;" << endl; + out << indent() << "if (that is not " << iter->first << " other) return false;" << '\n'; } else { - out << indent() << "if (!(that is " << iter->first << " other)) return false;" << endl; + out << indent() << "if (!(that is " << iter->first << " other)) return false;" << '\n'; } - out << indent() << "if (ReferenceEquals(instance, other)) return true;" << endl; - out << endl; - out << indent() << "return TCollections.Equals(instance, other);" << endl; + out << indent() << "if (ReferenceEquals(instance, other)) return true;" << '\n'; + out << '\n'; + out << indent() << "return TCollections.Equals(instance, other);" << '\n'; scope_down(out); - out << endl << endl; + out << '\n' << '\n'; - out << indent() << "public static int GetHashCode(this " << iter->first << " instance)" << endl; + out << indent() << "public static int GetHashCode(this " << iter->first << " instance)" << '\n'; scope_up(out); - out << indent() << "return TCollections.GetHashCode(instance);" << endl; + out << indent() << "return TCollections.GetHashCode(instance);" << '\n'; scope_down(out); - out << endl << endl; + out << '\n' << '\n'; if(! suppress_deepcopy) { - out << indent() << "public static " << iter->first << nullable_field_suffix(iter->second) << " " << DEEP_COPY_METHOD_NAME << "(this " << iter->first << nullable_field_suffix(iter->second) << " source)" << endl; + out << indent() << "public static " << iter->first << nullable_field_suffix(iter->second) << " " << DEEP_COPY_METHOD_NAME << "(this " << iter->first << nullable_field_suffix(iter->second) << " source)" << '\n'; scope_up(out); - out << indent() << "if (source == null)" << endl; + out << indent() << "if (source == null)" << '\n'; indent_up(); - out << indent() << "return null;" << endl << endl; + out << indent() << "return null;" << '\n' << '\n'; indent_down(); string suffix(""); string tmp_instance = tmp("tmp"); - out << indent() << "var " << tmp_instance << " = new " << iter->first << "(source.Count);" << endl; + if( (target_net_version < 5) && iter->second->is_set()) { + out << indent() << "var " << tmp_instance << " = new " << iter->first << "();" << '\n'; + } else { + out << indent() << "var " << tmp_instance << " = new " << iter->first << "(source.Count);" << '\n'; + } if( iter->second->is_map()) { t_map* tmap = static_cast(iter->second); @@ -723,7 +852,7 @@ void t_netstd_generator::generate_extensions(ostream& out, map bool null_key = type_can_be_null(tmap->get_key_type()); bool null_val = type_can_be_null(tmap->get_val_type()); - out << indent() << "foreach (var pair in source)" << endl; + out << indent() << "foreach (var pair in source)" << '\n'; indent_up(); if( target_net_version >= 6) { out << indent() << tmp_instance << ".Add(pair.Key" << copy_key; @@ -742,7 +871,7 @@ void t_netstd_generator::generate_extensions(ostream& out, map out << "pair.Value" << copy_val; } } - out << ");" << endl; + out << ");" << '\n'; indent_down(); } else if( iter->second->is_set() || iter->second->is_list()) { @@ -761,7 +890,7 @@ void t_netstd_generator::generate_extensions(ostream& out, map null_elm = type_can_be_null(tlist->get_elem_type()); } - out << indent() << "foreach (var elem in source)" << endl; + out << indent() << "foreach (var elem in source)" << '\n'; indent_up(); if( target_net_version >= 6) { out << indent() << tmp_instance << ".Add(elem" << copy_elm; @@ -774,13 +903,13 @@ void t_netstd_generator::generate_extensions(ostream& out, map out << "elem" << copy_elm; } } - out << ");" << endl; + out << ");" << '\n'; indent_down(); } - out << indent() << "return " << tmp_instance << ";" << endl; + out << indent() << "return " << tmp_instance << ";" << '\n'; scope_down(out); - out << endl << endl; + out << '\n' << '\n'; } } @@ -818,7 +947,7 @@ void t_netstd_generator::generate_netstd_struct(t_struct* tstruct, bool is_excep f_struct.open(f_struct_name.c_str()); reset_indent(); - f_struct << autogen_comment() << netstd_type_usings() << netstd_thrift_usings() << endl << endl; + f_struct << autogen_comment() << netstd_type_usings() << netstd_thrift_usings() << '\n' << '\n'; pragmas_and_directives(f_struct); generate_netstd_struct_definition(f_struct, tstruct, is_exception); @@ -835,7 +964,7 @@ void t_netstd_generator::generate_netstd_struct_definition(ostream& out, t_struc start_netstd_namespace(out); } - out << endl; + out << '\n'; generate_netstd_doc(out, tstruct); collect_extensions_types(tstruct); @@ -843,13 +972,14 @@ void t_netstd_generator::generate_netstd_struct_definition(ostream& out, t_struc if ((is_serialize_enabled() || is_wcf_enabled()) && !is_exception) { - out << indent() << "[DataContract(Namespace=\"" << wcf_namespace_ << "\")]" << endl; + out << indent() << "[DataContract(Namespace=\"" << wcf_namespace_ << "\")]" << '\n'; } bool is_final = tstruct->annotations_.find("final") != tstruct->annotations_.end(); string sharp_struct_name = type_name(tstruct, false); + generate_deprecation_attribute(out, tstruct->annotations_); out << indent() << "public " << (is_final ? "sealed " : "") << "partial class " << sharp_struct_name << " : "; if (is_exception) @@ -857,8 +987,8 @@ void t_netstd_generator::generate_netstd_struct_definition(ostream& out, t_struc out << "TException, "; } - out << "TBase" << endl - << indent() << "{" << endl; + out << "TBase" << '\n' + << indent() << "{" << '\n'; indent_up(); const vector& members = tstruct->get_members(); @@ -870,10 +1000,10 @@ void t_netstd_generator::generate_netstd_struct_definition(ostream& out, t_struc // if the field is required, then we use auto-properties if (!field_is_required((*m_iter))) { - out << indent() << "private " << declare_field(*m_iter, false, true, "_") << endl; + out << indent() << "private " << declare_field(*m_iter, false, true, "_") << '\n'; } } - out << endl; + out << '\n'; bool has_non_required_fields = false; bool has_required_fields = false; @@ -895,19 +1025,19 @@ void t_netstd_generator::generate_netstd_struct_definition(ostream& out, t_struc bool generate_isset = has_non_required_fields; if (generate_isset) { - out << endl; + out << '\n'; if (is_serialize_enabled() || is_wcf_enabled()) { - out << indent() << "[DataMember(Order = 1)]" << endl; + out << indent() << "[DataMember(Order = 1)]" << '\n'; } - out << indent() << "public Isset __isset;" << endl; + out << indent() << "public Isset __isset;" << '\n'; if (is_serialize_enabled() || is_wcf_enabled()) { - out << indent() << "[DataContract]" << endl; + out << indent() << "[DataContract]" << '\n'; } - out << indent() << "public struct Isset" << endl - << indent() << "{" << endl; + out << indent() << "public struct Isset" << '\n' + << indent() << "{" << '\n'; indent_up(); for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) @@ -919,18 +1049,18 @@ void t_netstd_generator::generate_netstd_struct_definition(ostream& out, t_struc { if (is_serialize_enabled() || is_wcf_enabled()) { - out << indent() << "[DataMember]" << endl; + out << indent() << "[DataMember]" << '\n'; } - out << indent() << "public bool " << get_isset_name(normalize_name((*m_iter)->get_name())) << ";" << endl; + out << indent() << "public bool " << get_isset_name(normalize_name((*m_iter)->get_name())) << ";" << '\n'; } } indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; if (generate_isset && (is_serialize_enabled() || is_wcf_enabled())) { - out << indent() << "#region XmlSerializer support" << endl << endl; + out << indent() << "#region XmlSerializer support" << '\n' << '\n'; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { @@ -939,22 +1069,22 @@ void t_netstd_generator::generate_netstd_struct_definition(ostream& out, t_struc // 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; + out << indent() << "public bool ShouldSerialize" << prop_name(*m_iter) << "()" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "return __isset." << get_isset_name(normalize_name((*m_iter)->get_name())) << ";" << endl; + out << indent() << "return __isset." << get_isset_name(normalize_name((*m_iter)->get_name())) << ";" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } } - out << indent() << "#endregion XmlSerializer support" << endl << endl; + out << indent() << "#endregion XmlSerializer support" << '\n' << '\n'; } } // We always want a default, no argument constructor for Reading - out << indent() << "public " << sharp_struct_name << "()" << endl - << indent() << "{" << endl; + out << indent() << "public " << sharp_struct_name << "()" << '\n' + << indent() << "{" << '\n'; indent_up(); for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) @@ -972,12 +1102,12 @@ void t_netstd_generator::generate_netstd_struct_definition(ostream& out, t_struc { 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." << get_isset_name(normalize_name((*m_iter)->get_name())) << " = true;" << endl; + out << indent() << "this.__isset." << get_isset_name(normalize_name((*m_iter)->get_name())) << " = true;" << '\n'; } } } indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; // if we have required fields, we add that CTOR too if (has_required_fields) @@ -999,20 +1129,20 @@ void t_netstd_generator::generate_netstd_struct_definition(ostream& out, t_struc out << type_name((*m_iter)->get_type()) << nullable_field_suffix(*m_iter) << " " << normalize_name((*m_iter)->get_name()); } } - out << ") : this()" << endl - << indent() << "{" << endl; + out << ") : this()" << '\n' + << indent() << "{" << '\n'; 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) << " = " << normalize_name((*m_iter)->get_name()) << ";" << endl; + out << indent() << "this." << prop_name(*m_iter) << " = " << normalize_name((*m_iter)->get_name()) << ";" << '\n'; } } indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } // DeepCopy() @@ -1032,7 +1162,7 @@ void t_netstd_generator::generate_netstd_struct_definition(ostream& out, t_struc generate_netstd_struct_tostring(out, tstruct); indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; // generate a corresponding WCF fault to wrap the exception if ((is_serialize_enabled() || is_wcf_enabled()) && is_exception) @@ -1050,13 +1180,14 @@ void t_netstd_generator::generate_netstd_struct_definition(ostream& out, t_struc void t_netstd_generator::generate_netstd_wcffault(ostream& out, t_struct* tstruct) { - out << endl; - out << indent() << "[DataContract]" << endl; + out << '\n'; + out << indent() << "[DataContract]" << '\n'; bool is_final = tstruct->annotations_.find("final") != tstruct->annotations_.end(); - out << indent() << "public " << (is_final ? "sealed " : "") << "partial class " << type_name(tstruct,false) << "Fault" << endl - << indent() << "{" << endl; + generate_deprecation_attribute(out, tstruct->annotations_); + out << indent() << "public " << (is_final ? "sealed " : "") << "partial class " << type_name(tstruct,false) << "Fault" << '\n' + << indent() << "{" << '\n'; indent_up(); const vector& members = tstruct->get_members(); @@ -1068,10 +1199,10 @@ void t_netstd_generator::generate_netstd_wcffault(ostream& out, t_struct* tstruc // if the field is required, then we use auto-properties if (!field_is_required((*m_iter))) { - out << indent() << "private " << declare_field(*m_iter, false, true, "_") << endl; + out << indent() << "private " << declare_field(*m_iter, false, true, "_") << '\n'; } } - out << endl; + out << '\n'; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { @@ -1079,7 +1210,7 @@ void t_netstd_generator::generate_netstd_wcffault(ostream& out, t_struct* tstruc } indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } void t_netstd_generator::generate_netstd_deepcopy_method(ostream& out, t_struct* tstruct, std::string sharp_struct_name) @@ -1091,8 +1222,8 @@ void t_netstd_generator::generate_netstd_deepcopy_method(ostream& out, t_struct* const vector& members = tstruct->get_members(); vector::const_iterator m_iter; - out << indent() << "public " << sharp_struct_name << " " << DEEP_COPY_METHOD_NAME << "()" << endl; - out << indent() << "{" << endl; + out << indent() << "public " << sharp_struct_name << " " << DEEP_COPY_METHOD_NAME << "()" << '\n'; + out << indent() << "{" << '\n'; indent_up(); // return directly if there are only required fields @@ -1100,10 +1231,10 @@ void t_netstd_generator::generate_netstd_deepcopy_method(ostream& out, t_struct* out << indent() << "var " << tmp_instance << " = new " << sharp_struct_name << "()"; bool inline_assignment = (target_net_version >= 6); if(inline_assignment) { - out << endl << indent() << "{" << endl; + out << '\n' << indent() << "{" << '\n'; indent_up(); } else { - out << endl; + out << ";\n"; } for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { @@ -1118,7 +1249,7 @@ void t_netstd_generator::generate_netstd_deepcopy_method(ostream& out, t_struct* if(inline_assignment) { if( null_allowed || (!is_required)) { // = has isset indent_down(); - out << indent() << "};" << endl; + out << indent() << "};" << '\n'; inline_assignment = false; } } @@ -1134,7 +1265,7 @@ void t_netstd_generator::generate_netstd_deepcopy_method(ostream& out, t_struct* out << "(" << type_name(ttype) << ")"; } out << "this." << prop_name(*m_iter) << copy_op; - out << (inline_assignment ? "," : ";") << endl; + out << (inline_assignment ? "," : ";") << '\n'; generate_null_check_end( out, *m_iter); if( !is_required) { @@ -1144,29 +1275,29 @@ void t_netstd_generator::generate_netstd_deepcopy_method(ostream& out, t_struct* } out << "__isset." << get_isset_name(normalize_name((*m_iter)->get_name())); out << " = this.__isset." << get_isset_name(normalize_name((*m_iter)->get_name())); - out << (inline_assignment ? "," : ";") << endl; + out << (inline_assignment ? "," : ";") << '\n'; } } if(inline_assignment) { indent_down(); - out << indent() << "};" << endl; + out << indent() << "};" << '\n'; } - out << indent() << "return " << tmp_instance << ";" << endl; + out << indent() << "return " << tmp_instance << ";" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } void t_netstd_generator::generate_netstd_struct_reader(ostream& out, t_struct* tstruct) { - out << indent() << "public async global::System.Threading.Tasks.Task ReadAsync(TProtocol iprot, CancellationToken " << CANCELLATION_TOKEN_NAME << ")" << endl - << indent() << "{" << endl; + out << indent() << "public async global::System.Threading.Tasks.Task ReadAsync(TProtocol iprot, CancellationToken " << CANCELLATION_TOKEN_NAME << ")" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "iprot.IncrementRecursionDepth();" << endl - << indent() << "try" << endl - << indent() << "{" << endl; + out << indent() << "iprot.IncrementRecursionDepth();" << '\n' + << indent() << "try" << '\n' + << indent() << "{" << '\n'; indent_up(); const vector& fields = tstruct->get_members(); @@ -1177,90 +1308,90 @@ void t_netstd_generator::generate_netstd_struct_reader(ostream& out, t_struct* t { if (field_is_required(*f_iter)) { - out << indent() << "bool isset_" << (*f_iter)->get_name() << " = false;" << endl; + out << indent() << "bool isset_" << (*f_iter)->get_name() << " = false;" << '\n'; } } - out << indent() << "TField field;" << endl - << indent() << "await iprot.ReadStructBeginAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl - << indent() << "while (true)" << endl - << indent() << "{" << endl; + out << indent() << "TField field;" << '\n' + << indent() << "await iprot.ReadStructBeginAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n' + << indent() << "while (true)" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "field = await iprot.ReadFieldBeginAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl - << indent() << "if (field.Type == TType.Stop)" << endl - << indent() << "{" << endl; + out << indent() << "field = await iprot.ReadFieldBeginAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n' + << indent() << "if (field.Type == TType.Stop)" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "break;" << endl; + out << indent() << "break;" << '\n'; indent_down(); - out << indent() << "}" << endl << endl - << indent() << "switch (field.ID)" << endl - << indent() << "{" << endl; + out << indent() << "}" << '\n' << '\n' + << indent() << "switch (field.ID)" << '\n' + << indent() << "{" << '\n'; 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; + out << indent() << "case " << (*f_iter)->get_key() << ":" << '\n'; indent_up(); - out << indent() << "if (field.Type == " << type_to_enum((*f_iter)->get_type()) << ")" << endl - << indent() << "{" << endl; + out << indent() << "if (field.Type == " << type_to_enum((*f_iter)->get_type()) << ")" << '\n' + << indent() << "{" << '\n'; indent_up(); generate_deserialize_field(out, *f_iter); if (is_required) { - out << indent() << "isset_" << (*f_iter)->get_name() << " = true;" << endl; + out << indent() << "isset_" << (*f_iter)->get_name() << " = true;" << '\n'; } indent_down(); - out << indent() << "}" << endl - << indent() << "else" << endl - << indent() << "{" << endl; + out << indent() << "}" << '\n' + << indent() << "else" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "await TProtocolUtil.SkipAsync(iprot, field.Type, " << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << "await TProtocolUtil.SkipAsync(iprot, field.Type, " << CANCELLATION_TOKEN_NAME << ");" << '\n'; indent_down(); - out << indent() << "}" << endl - << indent() << "break;" << endl; + out << indent() << "}" << '\n' + << indent() << "break;" << '\n'; indent_down(); } - out << indent() << "default: " << endl; + out << indent() << "default: " << '\n'; indent_up(); - out << indent() << "await TProtocolUtil.SkipAsync(iprot, field.Type, " << CANCELLATION_TOKEN_NAME << ");" << endl - << indent() << "break;" << endl; + out << indent() << "await TProtocolUtil.SkipAsync(iprot, field.Type, " << CANCELLATION_TOKEN_NAME << ");" << '\n' + << indent() << "break;" << '\n'; indent_down(); indent_down(); - out << indent() << "}" << endl - << endl - << indent() << "await iprot.ReadFieldEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << "}" << '\n' + << '\n' + << indent() << "await iprot.ReadFieldEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n'; indent_down(); - out << indent() << "}" << endl - << endl - << indent() << "await iprot.ReadStructEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << "}" << '\n' + << '\n' + << indent() << "await iprot.ReadStructEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n'; 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; + out << indent() << "if (!isset_" << (*f_iter)->get_name() << ")" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "throw new TProtocolException(TProtocolException.INVALID_DATA);" << endl; + out << indent() << "throw new TProtocolException(TProtocolException.INVALID_DATA);" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } } indent_down(); - out << indent() << "}" << endl; - out << indent() << "finally" << endl - << indent() << "{" << endl; + out << indent() << "}" << '\n'; + out << indent() << "finally" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "iprot.DecrementRecursionDepth();" << endl; + out << indent() << "iprot.DecrementRecursionDepth();" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } @@ -1284,8 +1415,8 @@ void t_netstd_generator::generate_null_check_begin(ostream& out, t_field* tfield out << "__isset." << get_isset_name(normalize_name(tfield->get_name())); } - out << ")" << endl - << indent() << "{" << endl; + out << ")" << '\n' + << indent() << "{" << '\n'; indent_up(); } } @@ -1297,19 +1428,19 @@ void t_netstd_generator::generate_null_check_end(ostream& out, t_field* tfield) if( null_allowed || (!is_required)) { indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } } void t_netstd_generator::generate_netstd_struct_writer(ostream& out, t_struct* tstruct) { - out << indent() << "public async global::System.Threading.Tasks.Task WriteAsync(TProtocol oprot, CancellationToken " << CANCELLATION_TOKEN_NAME << ")" << endl - << indent() << "{" << endl; + out << indent() << "public async global::System.Threading.Tasks.Task WriteAsync(TProtocol oprot, CancellationToken " << CANCELLATION_TOKEN_NAME << ")" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "oprot.IncrementRecursionDepth();" << endl - << indent() << "try" << endl - << indent() << "{" << endl; + out << indent() << "oprot.IncrementRecursionDepth();" << '\n' + << indent() << "try" << '\n' + << indent() << "{" << '\n'; indent_up(); string name = tstruct->get_name(); @@ -1317,57 +1448,57 @@ void t_netstd_generator::generate_netstd_struct_writer(ostream& out, t_struct* t vector::const_iterator f_iter; string tmpvar = tmp("tmp"); - out << indent() << "var " << tmpvar << " = new TStruct(\"" << name << "\");" << endl - << indent() << "await oprot.WriteStructBeginAsync(" << tmpvar << ", " << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << "var " << tmpvar << " = new TStruct(\"" << name << "\");" << '\n' + << indent() << "await oprot.WriteStructBeginAsync(" << tmpvar << ", " << CANCELLATION_TOKEN_NAME << ");" << '\n'; if (fields.size() > 0) { tmpvar = tmp("tmp"); if(target_net_version >= 8) { - out << indent() << "#pragma warning disable IDE0017 // simplified init" << endl; + out << indent() << "#pragma warning disable IDE0017 // simplified init" << '\n'; } - out << indent() << "var " << tmpvar << " = new TField();" << endl; + out << indent() << "var " << tmpvar << " = new TField();" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { generate_null_check_begin( out, *f_iter); - out << indent() << tmpvar << ".Name = \"" << (*f_iter)->get_name() << "\";" << endl - << indent() << tmpvar << ".Type = " << type_to_enum((*f_iter)->get_type()) << ";" << endl - << indent() << tmpvar << ".ID = " << (*f_iter)->get_key() << ";" << endl - << indent() << "await oprot.WriteFieldBeginAsync(" << tmpvar << ", " << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << tmpvar << ".Name = \"" << (*f_iter)->get_name() << "\";" << '\n' + << indent() << tmpvar << ".Type = " << type_to_enum((*f_iter)->get_type()) << ";" << '\n' + << indent() << tmpvar << ".ID = " << (*f_iter)->get_key() << ";" << '\n' + << indent() << "await oprot.WriteFieldBeginAsync(" << tmpvar << ", " << CANCELLATION_TOKEN_NAME << ");" << '\n'; generate_serialize_field(out, *f_iter); - out << indent() << "await oprot.WriteFieldEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << "await oprot.WriteFieldEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n'; generate_null_check_end(out, *f_iter); } if(target_net_version >= 8) { - out << indent() << "#pragma warning restore IDE0017 // simplified init" << endl; + out << indent() << "#pragma warning restore IDE0017 // simplified init" << '\n'; } } - out << indent() << "await oprot.WriteFieldStopAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl - << indent() << "await oprot.WriteStructEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << "await oprot.WriteFieldStopAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n' + << indent() << "await oprot.WriteStructEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n'; indent_down(); - out << indent() << "}" << endl - << indent() << "finally" << endl - << indent() << "{" << endl; + out << indent() << "}" << '\n' + << indent() << "finally" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "oprot.DecrementRecursionDepth();" << endl; + out << indent() << "oprot.DecrementRecursionDepth();" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } void t_netstd_generator::generate_netstd_struct_result_writer(ostream& out, t_struct* tstruct) { - out << indent() << "public async global::System.Threading.Tasks.Task WriteAsync(TProtocol oprot, CancellationToken " << CANCELLATION_TOKEN_NAME << ")" << endl - << indent() << "{" << endl; + out << indent() << "public async global::System.Threading.Tasks.Task WriteAsync(TProtocol oprot, CancellationToken " << CANCELLATION_TOKEN_NAME << ")" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "oprot.IncrementRecursionDepth();" << endl - << indent() << "try" << endl - << indent() << "{" << endl; + out << indent() << "oprot.IncrementRecursionDepth();" << '\n' + << indent() << "try" << '\n' + << indent() << "{" << '\n'; indent_up(); string name = tstruct->get_name(); @@ -1375,85 +1506,85 @@ void t_netstd_generator::generate_netstd_struct_result_writer(ostream& out, t_st vector::const_iterator f_iter; string tmpvar = tmp("tmp"); - out << indent() << "var " << tmpvar << " = new TStruct(\"" << name << "\");" << endl - << indent() << "await oprot.WriteStructBeginAsync(" << tmpvar << ", " << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << "var " << tmpvar << " = new TStruct(\"" << name << "\");" << '\n' + << indent() << "await oprot.WriteStructBeginAsync(" << tmpvar << ", " << CANCELLATION_TOKEN_NAME << ");" << '\n'; if (fields.size() > 0) { tmpvar = tmp("tmp"); if(target_net_version >= 8) { - out << indent() << "#pragma warning disable IDE0017 // simplified init" << endl; + out << indent() << "#pragma warning disable IDE0017 // simplified init" << '\n'; } - out << indent() << "var " << tmpvar << " = new TField();" << endl; + out << indent() << "var " << tmpvar << " = new TField();" << '\n'; bool first = true; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if (first) { first = false; - out << endl << indent() << "if"; + out << '\n' << indent() << "if"; } else { out << indent() << "else if"; } - out << "(this.__isset." << get_isset_name(normalize_name((*f_iter)->get_name())) << ")" << endl - << indent() << "{" << endl; + out << "(this.__isset." << get_isset_name(normalize_name((*f_iter)->get_name())) << ")" << '\n' + << indent() << "{" << '\n'; 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; + out << indent() << "if (" << prop_name(*f_iter) << " != null)" << '\n' + << indent() << "{" << '\n'; indent_up(); } - out << indent() << tmpvar << ".Name = \"" << prop_name(*f_iter) << "\";" << endl - << indent() << tmpvar << ".Type = " << type_to_enum((*f_iter)->get_type()) << ";" << endl - << indent() << tmpvar << ".ID = " << (*f_iter)->get_key() << ";" << endl - << indent() << "await oprot.WriteFieldBeginAsync(" << tmpvar << ", " << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << tmpvar << ".Name = \"" << prop_name(*f_iter) << "\";" << '\n' + << indent() << tmpvar << ".Type = " << type_to_enum((*f_iter)->get_type()) << ";" << '\n' + << indent() << tmpvar << ".ID = " << (*f_iter)->get_key() << ";" << '\n' + << indent() << "await oprot.WriteFieldBeginAsync(" << tmpvar << ", " << CANCELLATION_TOKEN_NAME << ");" << '\n'; generate_serialize_field(out, *f_iter); - out << indent() << "await oprot.WriteFieldEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << "await oprot.WriteFieldEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n'; if (null_allowed) { indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } if(target_net_version >= 8) { - out << indent() << "#pragma warning restore IDE0017 // simplified init" << endl; + out << indent() << "#pragma warning restore IDE0017 // simplified init" << '\n'; } } - out << indent() << "await oprot.WriteFieldStopAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl - << indent() << "await oprot.WriteStructEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << "await oprot.WriteFieldStopAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n' + << indent() << "await oprot.WriteStructEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n'; indent_down(); - out << indent() << "}" << endl - << indent() << "finally" << endl - << indent() << "{" << endl; + out << indent() << "}" << '\n' + << indent() << "finally" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "oprot.DecrementRecursionDepth();" << endl; + out << indent() << "oprot.DecrementRecursionDepth();" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } void t_netstd_generator::generate_netstd_struct_tostring(ostream& out, t_struct* tstruct) { string tmpvar = tmp("tmp"); - out << indent() << "public override string ToString()" << endl - << indent() << "{" << endl; + out << indent() << "public override string ToString()" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "var " << tmpvar << " = new StringBuilder(\"" << tstruct->get_name() << "(\");" << endl; + out << indent() << "var " << tmpvar << " = new StringBuilder(\"" << tstruct->get_name() << "(\");" << '\n'; const vector& fields = tstruct->get_members(); vector::const_iterator f_iter; @@ -1464,7 +1595,7 @@ void t_netstd_generator::generate_netstd_struct_tostring(ostream& out, t_struct* { if (!field_is_required((*f_iter))) { - out << indent() << "int " << tmp_count.c_str() << " = 0;" << endl; + out << indent() << "int " << tmp_count.c_str() << " = 0;" << '\n'; useFirstFlag = true; } break; @@ -1479,15 +1610,15 @@ void t_netstd_generator::generate_netstd_struct_tostring(ostream& out, t_struct* if (useFirstFlag && (!had_required)) { - out << indent() << "if(0 < " << tmp_count.c_str() << (is_required ? "" : "++") << ") { " << tmpvar << ".Append(\", \"); }" << endl; - out << indent() << tmpvar << ".Append(\"" << prop_name(*f_iter) << ": \");" << endl; + out << indent() << "if(0 < " << tmp_count.c_str() << (is_required ? "" : "++") << ") { " << tmpvar << ".Append(\", \"); }" << '\n'; + out << indent() << tmpvar << ".Append(\"" << prop_name(*f_iter) << ": \");" << '\n'; } else { - out << indent() << tmpvar << ".Append(\", " << prop_name(*f_iter) << ": \");" << endl; + out << indent() << tmpvar << ".Append(\", " << prop_name(*f_iter) << ": \");" << '\n'; } - out << indent() << prop_name(*f_iter) << ".ToString(" << tmpvar << ");" << endl; + out << indent() << prop_name(*f_iter) << ".ToString(" << tmpvar << ");" << '\n'; generate_null_check_end(out, *f_iter); if (is_required) { @@ -1495,10 +1626,10 @@ void t_netstd_generator::generate_netstd_struct_tostring(ostream& out, t_struct* } } - out << indent() << tmpvar << ".Append(')');" << endl - << indent() << "return " << tmpvar << ".ToString();" << endl; + out << indent() << tmpvar << ".Append(')');" << '\n' + << indent() << "return " << tmpvar << ".ToString();" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } void t_netstd_generator::generate_netstd_union(t_struct* tunion) @@ -1511,7 +1642,7 @@ void t_netstd_generator::generate_netstd_union(t_struct* tunion) f_union.open(f_union_name.c_str()); reset_indent(); - f_union << autogen_comment() << netstd_type_usings() << netstd_thrift_usings() << endl << endl; + f_union << autogen_comment() << netstd_type_usings() << netstd_thrift_usings() << '\n' << '\n'; pragmas_and_directives(f_union); generate_netstd_union_definition(f_union, tunion); @@ -1526,75 +1657,76 @@ void t_netstd_generator::generate_netstd_union_definition(ostream& out, t_struct // Let's define the class first start_netstd_namespace(out); - out << indent() << "public abstract partial class " << normalize_name(tunion->get_name()) << " : TUnionBase" << endl; - out << indent() << "{" << endl; + generate_deprecation_attribute(out, tunion->annotations_); + out << indent() << "public abstract partial class " << normalize_name(tunion->get_name()) << " : TUnionBase" << '\n'; + out << indent() << "{" << '\n'; indent_up(); - out << indent() << "public abstract global::System.Threading.Tasks.Task WriteAsync(TProtocol tProtocol, CancellationToken " << CANCELLATION_TOKEN_NAME << ");" << endl - << indent() << "public readonly int Isset;" << endl - << indent() << "public abstract object" << nullable_suffix() <<" Data { get; }" << endl - << indent() << "protected " << normalize_name(tunion->get_name()) << "(int isset)" << endl - << indent() << "{" << endl; + out << indent() << "public abstract global::System.Threading.Tasks.Task WriteAsync(TProtocol tProtocol, CancellationToken " << CANCELLATION_TOKEN_NAME << ");" << '\n' + << indent() << "public readonly int Isset;" << '\n' + << indent() << "public abstract object" << nullable_suffix() <<" Data { get; }" << '\n' + << indent() << "protected " << normalize_name(tunion->get_name()) << "(int isset)" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "Isset = isset;" << endl; + out << indent() << "Isset = isset;" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; const vector& fields = tunion->get_members(); vector::const_iterator f_iter; - out << indent() << "public override bool Equals(object" << nullable_suffix() << " that)" << endl; + out << indent() << "public override bool Equals(object" << nullable_suffix() << " that)" << '\n'; scope_up(out); if( target_net_version >= 6) { - out << indent() << "if (that is not " << tunion->get_name() << " other) return false;" << endl; + out << indent() << "if (that is not " << tunion->get_name() << " other) return false;" << '\n'; } else { - out << indent() << "if (!(that is " << tunion->get_name() << " other)) return false;" << endl; + out << indent() << "if (!(that is " << tunion->get_name() << " other)) return false;" << '\n'; } - out << indent() << "if (ReferenceEquals(this, other)) return true;" << endl; - out << endl; - out << indent() << "if(this.Isset != other.Isset) return false;" << endl; - out << endl; + out << indent() << "if (ReferenceEquals(this, other)) return true;" << '\n'; + out << '\n'; + out << indent() << "if(this.Isset != other.Isset) return false;" << '\n'; + out << '\n'; if(target_net_version >= 6) { - out << indent() << "return Isset switch" << endl; + out << indent() << "return Isset switch" << '\n'; scope_up(out); for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { bool needs_typecast = false; string suffix(""); get_deep_copy_method_call((*f_iter)->get_type(), false, needs_typecast, suffix); - out << indent() << (*f_iter)->get_key() << " => Equals(As_" << (*f_iter)->get_name() << ", other.As_" << (*f_iter)->get_name() << ")," << endl; + out << indent() << (*f_iter)->get_key() << " => Equals(As_" << (*f_iter)->get_name() << ", other.As_" << (*f_iter)->get_name() << ")," << '\n'; } - out << indent() << "_ => true," << endl; + out << indent() << "_ => true," << '\n'; indent_down(); - out << indent() << "};" << endl; + out << indent() << "};" << '\n'; } else { - out << indent() << "switch (Isset)" << endl; + out << indent() << "switch (Isset)" << '\n'; scope_up(out); for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { bool needs_typecast = false; string suffix(""); get_deep_copy_method_call((*f_iter)->get_type(), false, needs_typecast, suffix); - out << indent() << "case " << (*f_iter)->get_key() << ":" << endl; + out << indent() << "case " << (*f_iter)->get_key() << ":" << '\n'; indent_up(); - out << indent() << "return Equals(As_" << (*f_iter)->get_name() << ", other.As_" << (*f_iter)->get_name() << ");" << endl; + out << indent() << "return Equals(As_" << (*f_iter)->get_name() << ", other.As_" << (*f_iter)->get_name() << ");" << '\n'; indent_down(); } - out << indent() << "default:" << endl; + out << indent() << "default:" << '\n'; indent_up(); - out << indent() << "return true;" << endl; + out << indent() << "return true;" << '\n'; indent_down(); scope_down(out); } scope_down(out); - out << endl; + out << '\n'; - out << indent() << "public override int GetHashCode()" << endl; - out << indent() << "{" << endl; + out << indent() << "public override int GetHashCode()" << '\n'; + out << indent() << "{" << '\n'; indent_up(); if(target_net_version >= 6) { - out << indent() << "return Isset switch" << endl; - out << indent() << "{" << endl; + out << indent() << "return Isset switch" << '\n'; + out << indent() << "{" << '\n'; indent_up(); for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { @@ -1603,108 +1735,108 @@ void t_netstd_generator::generate_netstd_union_definition(ostream& out, t_struct if( null_coalesce.size() > 0) { out << " ?? 0"; } - out << "," << endl; + out << "," << '\n'; } - out << indent() << "_ => (new ___undefined()).GetHashCode()" << endl; + out << indent() << "_ => (new ___undefined()).GetHashCode()" << '\n'; indent_down(); - out << indent() << "};" << endl; + out << indent() << "};" << '\n'; } else { - out << indent() << "switch (Isset)" << endl; - out << indent() << "{" << endl; + out << indent() << "switch (Isset)" << '\n'; + out << indent() << "{" << '\n'; indent_up(); for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { string null_coalesce(is_nullable_type((*f_iter)->get_type()) ? "?" : ""); - out << indent() << "case " << (*f_iter)->get_key() << ":" << endl; + out << indent() << "case " << (*f_iter)->get_key() << ":" << '\n'; indent_up(); out << indent() << "return As_" << (*f_iter)->get_name() << null_coalesce << ".GetHashCode()"; if( null_coalesce.size() > 0) { out << " ?? 0"; } - out << ";" << endl; + out << ";" << '\n'; indent_down(); } - out << indent() << "default:" << endl; + out << indent() << "default:" << '\n'; indent_up(); - out << indent() << "return (new ___undefined()).GetHashCode();" << endl; + out << indent() << "return (new ___undefined()).GetHashCode();" << '\n'; indent_down(); indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; if( ! suppress_deepcopy) { - out << indent() << "public " << tunion->get_name() << " " << DEEP_COPY_METHOD_NAME << "()" << endl; - out << indent() << "{" << endl; + out << indent() << "public " << tunion->get_name() << " " << DEEP_COPY_METHOD_NAME << "()" << '\n'; + out << indent() << "{" << '\n'; indent_up(); if(target_net_version >= 6) { - out << indent() << "return Isset switch" << endl; - out << indent() << "{" << endl; + out << indent() << "return Isset switch" << '\n'; + out << indent() << "{" << '\n'; indent_up(); for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { bool needs_typecast = false; string suffix(""); string copy_op = get_deep_copy_method_call((*f_iter)->get_type(), false, needs_typecast, suffix); - out << indent() << (*f_iter)->get_key() << " => new " << (*f_iter)->get_name() << "(As_" << (*f_iter)->get_name() << suffix << copy_op << ")," << endl; + out << indent() << (*f_iter)->get_key() << " => new " << (*f_iter)->get_name() << "(As_" << (*f_iter)->get_name() << suffix << copy_op << ")," << '\n'; } - out << indent() << "_ => new ___undefined()" << endl; + out << indent() << "_ => new ___undefined()" << '\n'; indent_down(); - out << indent() << "};" << endl; + out << indent() << "};" << '\n'; } else { - out << indent() << "switch (Isset)" << endl; - out << indent() << "{" << endl; + out << indent() << "switch (Isset)" << '\n'; + out << indent() << "{" << '\n'; indent_up(); for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { bool needs_typecast = false; string suffix(""); string copy_op = get_deep_copy_method_call((*f_iter)->get_type(), false, needs_typecast, suffix); - out << indent() << "case " << (*f_iter)->get_key() << ":" << endl; + out << indent() << "case " << (*f_iter)->get_key() << ":" << '\n'; indent_up(); - out << indent() << "return new " << (*f_iter)->get_name() << "(As_" << (*f_iter)->get_name() << suffix << copy_op << ");" << endl; + out << indent() << "return new " << (*f_iter)->get_name() << "(As_" << (*f_iter)->get_name() << suffix << copy_op << ");" << '\n'; indent_down(); } - out << indent() << "default:" << endl; + out << indent() << "default:" << '\n'; indent_up(); - out << indent() << "return new ___undefined();" << endl; + out << indent() << "return new ___undefined();" << '\n'; indent_down(); indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } - out << indent() << "public class ___undefined : " << tunion->get_name() << endl; - out << indent() << "{" << endl; + out << indent() << "public class ___undefined : " << tunion->get_name() << '\n'; + out << indent() << "{" << '\n'; indent_up(); - out << indent() << "public override object" << nullable_suffix() <<" Data { get { return null; } }" << endl - << indent() << "public ___undefined() : base(0) {}" << endl << endl; + out << indent() << "public override object" << nullable_suffix() <<" Data { get { return null; } }" << '\n' + << indent() << "public ___undefined() : base(0) {}" << '\n' << '\n'; if( ! suppress_deepcopy) { - out << indent() << "public new ___undefined " << DEEP_COPY_METHOD_NAME << "()" << endl; - out << indent() << "{" << endl; + out << indent() << "public new ___undefined " << DEEP_COPY_METHOD_NAME << "()" << '\n'; + out << indent() << "{" << '\n'; indent_up(); - out << indent() << "return new ___undefined();" << endl; + out << indent() << "return new ___undefined();" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } t_struct undefined_struct(program_,"___undefined"); generate_netstd_struct_equals(out, &undefined_struct); generate_netstd_struct_hashcode(out, &undefined_struct); - out << indent() << "public override global::System.Threading.Tasks.Task WriteAsync(TProtocol oprot, CancellationToken " << CANCELLATION_TOKEN_NAME << ")" << endl - << indent() << "{" << endl; + out << indent() << "public override global::System.Threading.Tasks.Task WriteAsync(TProtocol oprot, CancellationToken " << CANCELLATION_TOKEN_NAME << ")" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "throw new TProtocolException( TProtocolException.INVALID_DATA, \"Cannot persist an union type which is not set.\");" << endl; + out << indent() << "throw new TProtocolException( TProtocolException.INVALID_DATA, \"Cannot persist an union type which is not set.\");" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { @@ -1714,128 +1846,128 @@ void t_netstd_generator::generate_netstd_union_definition(ostream& out, t_struct generate_netstd_union_reader(out, tunion); indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; 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()) << nullable_field_suffix(tfield) << " As_" << tfield->get_name() << endl; - out << indent() << "{" << endl; + out << indent() << "public " << type_name(tfield->get_type()) << nullable_field_suffix(tfield) << " As_" << tfield->get_name() << '\n'; + out << indent() << "{" << '\n'; indent_up(); - out << indent() << "get" << endl; - out << indent() << "{" << endl; + out << indent() << "get" << '\n'; + out << indent() << "{" << '\n'; indent_up(); out << indent() << "return (" << tfield->get_key() << " == Isset) && (Data != null)" << " ? (" << type_name(tfield->get_type()) << nullable_field_suffix(tfield) << ")Data" << " : default" << (target_net_version >= 6 ? "" : ("(" + type_name(tfield->get_type()) + ")")) - << ";" << endl; + << ";" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; indent_down(); - out << indent() << "}" << endl - << endl; + out << indent() << "}" << '\n' + << '\n'; - out << indent() << "public class " << normalize_name(tfield->get_name()) << " : " << normalize_name(tunion->get_name()) << endl; - out << indent() << "{" << endl; + out << indent() << "public class " << normalize_name(tfield->get_name()) << " : " << normalize_name(tunion->get_name()) << '\n'; + out << indent() << "{" << '\n'; indent_up(); - out << indent() << "private readonly " << type_name(tfield->get_type()) << " _data;" << endl - << indent() << "public override object" << nullable_suffix() <<" Data { get { return _data; } }" << endl - << indent() << "public " << normalize_name(tfield->get_name()) << "(" << type_name(tfield->get_type()) << " data) : base("<< tfield->get_key() <<")" << endl - << indent() << "{" << endl; + out << indent() << "private readonly " << type_name(tfield->get_type()) << " _data;" << '\n' + << indent() << "public override object" << nullable_suffix() <<" Data { get { return _data; } }" << '\n' + << indent() << "public " << normalize_name(tfield->get_name()) << "(" << type_name(tfield->get_type()) << " data) : base("<< tfield->get_key() <<")" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "this._data = data;" << endl; + out << indent() << "this._data = data;" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; if( ! suppress_deepcopy) { - out << indent() << "public new " << normalize_name(tfield->get_name()) << " " << DEEP_COPY_METHOD_NAME << "()" << endl; - out << indent() << "{" << endl; + out << indent() << "public new " << normalize_name(tfield->get_name()) << " " << DEEP_COPY_METHOD_NAME << "()" << '\n'; + out << indent() << "{" << '\n'; indent_up(); bool needs_typecast = false; string suffix(""); string copy_op = get_deep_copy_method_call(tfield->get_type(), true, needs_typecast, suffix); - out << indent() << "return new " << normalize_name(tfield->get_name()) << "(_data" << copy_op << ");" << endl; + out << indent() << "return new " << normalize_name(tfield->get_name()) << "(_data" << copy_op << ");" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } - out << indent() << "public override bool Equals(object" << nullable_suffix() << " that)" << endl; - out << indent() << "{" << endl; + out << indent() << "public override bool Equals(object" << nullable_suffix() << " that)" << '\n'; + out << indent() << "{" << '\n'; indent_up(); if(target_net_version >= 6) { - out << indent() << "if (that is not " << tunion->get_name() << " other) return false;" << endl; + out << indent() << "if (that is not " << tunion->get_name() << " other) return false;" << '\n'; } else { - out << indent() << "if (!(that is " << tunion->get_name() << " other)) return false;" << endl; + out << indent() << "if (!(that is " << tunion->get_name() << " other)) return false;" << '\n'; } - out << indent() << "if (ReferenceEquals(this, other)) return true;" << endl; - out << endl; - out << indent() << "return Equals( _data, other.As_" << tfield->get_name() << ");" << endl; + out << indent() << "if (ReferenceEquals(this, other)) return true;" << '\n'; + out << '\n'; + out << indent() << "return Equals( _data, other.As_" << tfield->get_name() << ");" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; - out << indent() << "public override int GetHashCode()" << endl; - out << indent() << "{" << endl; + out << indent() << "public override int GetHashCode()" << '\n'; + out << indent() << "{" << '\n'; indent_up(); - out << indent() << "return _data.GetHashCode();" << endl; + out << indent() << "return _data.GetHashCode();" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; - out << indent() << "public override async global::System.Threading.Tasks.Task WriteAsync(TProtocol oprot, CancellationToken " << CANCELLATION_TOKEN_NAME << ") {" << endl; + out << indent() << "public override async global::System.Threading.Tasks.Task WriteAsync(TProtocol oprot, CancellationToken " << CANCELLATION_TOKEN_NAME << ") {" << '\n'; indent_up(); - out << indent() << "oprot.IncrementRecursionDepth();" << endl - << indent() << "try" << endl - << indent() << "{" << endl; + out << indent() << "oprot.IncrementRecursionDepth();" << '\n' + << indent() << "try" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "var struc = new TStruct(\"" << tunion->get_name() << "\");" << endl - << indent() << "await oprot.WriteStructBeginAsync(struc, " << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << "var struc = new TStruct(\"" << tunion->get_name() << "\");" << '\n' + << indent() << "await oprot.WriteStructBeginAsync(struc, " << CANCELLATION_TOKEN_NAME << ");" << '\n'; - out << indent() << "var field = new TField()" << endl; - out << indent() << "{" << endl; + out << indent() << "var field = new TField()" << '\n'; + out << indent() << "{" << '\n'; indent_up(); - out << indent() << "Name = \"" << tfield->get_name() << "\"," << endl - << indent() << "Type = " << type_to_enum(tfield->get_type()) << "," << endl - << indent() << "ID = " << tfield->get_key() << endl; + out << indent() << "Name = \"" << tfield->get_name() << "\"," << '\n' + << indent() << "Type = " << type_to_enum(tfield->get_type()) << "," << '\n' + << indent() << "ID = " << tfield->get_key() << '\n'; indent_down(); - out << indent() << "};" << endl; - out << indent() << "await oprot.WriteFieldBeginAsync(field, " << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << "};" << '\n'; + out << indent() << "await oprot.WriteFieldBeginAsync(field, " << CANCELLATION_TOKEN_NAME << ");" << '\n'; generate_serialize_field(out, tfield, "_data", true, false); - out << indent() << "await oprot.WriteFieldEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl - << indent() << "await oprot.WriteFieldStopAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl - << indent() << "await oprot.WriteStructEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << "await oprot.WriteFieldEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n' + << indent() << "await oprot.WriteFieldStopAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n' + << indent() << "await oprot.WriteStructEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n'; indent_down(); - out << indent() << "}" << endl - << indent() << "finally" << endl - << indent() << "{" << endl; + out << indent() << "}" << '\n' + << indent() << "finally" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "oprot.DecrementRecursionDepth();" << endl; + out << indent() << "oprot.DecrementRecursionDepth();" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } void t_netstd_generator::generate_netstd_struct_equals(ostream& out, t_struct* tstruct) { - out << indent() << "public override bool Equals(object" << nullable_suffix() << " that)" << endl - << indent() << "{" << endl; + out << indent() << "public override bool Equals(object" << nullable_suffix() << " that)" << '\n' + << indent() << "{" << '\n'; indent_up(); if(target_net_version >= 6) { - out << indent() << "if (that is not " << type_name(tstruct,false) << " other) return false;" << endl; + out << indent() << "if (that is not " << type_name(tstruct,false) << " other) return false;" << '\n'; } else { - out << indent() << "if (!(that is " << type_name(tstruct,false) << " other)) return false;" << endl; + out << indent() << "if (!(that is " << type_name(tstruct,false) << " other)) return false;" << '\n'; } - out << indent() << "if (ReferenceEquals(this, other)) return true;" << endl; + out << indent() << "if (ReferenceEquals(this, other)) return true;" << '\n'; const vector& fields = tstruct->get_members(); @@ -1853,7 +1985,7 @@ void t_netstd_generator::generate_netstd_struct_equals(ostream& out, t_struct* t } else { - out << endl; + out << '\n'; out << indent() << "&& "; } if (!field_is_required((*f_iter))) @@ -1879,25 +2011,25 @@ void t_netstd_generator::generate_netstd_struct_equals(ostream& out, t_struct* t } if (first) { - out << indent() << "return true;" << endl; + out << indent() << "return true;" << '\n'; } else { - out << ";" << endl; + out << ";" << '\n'; indent_down(); } indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } void t_netstd_generator::generate_netstd_struct_hashcode(ostream& out, t_struct* tstruct) { - out << indent() << "public override int GetHashCode() {" << endl; + out << indent() << "public override int GetHashCode() {" << '\n'; indent_up(); - out << indent() << "int hashcode = 157;" << endl; - out << indent() << "unchecked {" << endl; + out << indent() << "int hashcode = 157;" << '\n'; + out << indent() << "unchecked {" << '\n'; indent_up(); const vector& fields = tstruct->get_members(); @@ -1915,17 +2047,17 @@ void t_netstd_generator::generate_netstd_struct_hashcode(ostream& out, t_struct* else { out << prop_name(*f_iter) << ".GetHashCode()"; } - out << ";" << endl; + out << ";" << '\n'; generate_null_check_end(out, *f_iter); } indent_down(); - out << indent() << "}" << endl; - out << indent() << "return hashcode;" << endl; + out << indent() << "}" << '\n'; + out << indent() << "return hashcode;" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } void t_netstd_generator::generate_service(t_service* tservice) @@ -1937,13 +2069,13 @@ void t_netstd_generator::generate_service(t_service* tservice) f_service.open(f_service_name.c_str()); reset_indent(); - f_service << autogen_comment() << netstd_type_usings() << netstd_thrift_usings() << endl << endl; + f_service << autogen_comment() << netstd_type_usings() << netstd_thrift_usings() << '\n' << '\n'; pragmas_and_directives(f_service); start_netstd_namespace(f_service); - f_service << indent() << "public partial class " << normalize_name(service_name_) << endl - << indent() << "{" << endl; + f_service << indent() << "public partial class " << normalize_name(service_name_) << '\n' + << indent() << "{" << '\n'; indent_up(); generate_service_interface(f_service, tservice); @@ -1952,7 +2084,7 @@ void t_netstd_generator::generate_service(t_service* tservice) generate_service_helpers(f_service, tservice); indent_down(); - f_service << indent() << "}" << endl; + f_service << indent() << "}" << '\n'; end_netstd_namespace(f_service); f_service.close(); @@ -1970,18 +2102,19 @@ void t_netstd_generator::generate_service_interface(ostream& out, t_service* tse extends_iface = " : " + extends + ".IAsync"; } - //out << endl << endl; + //out << '\n' << '\n'; generate_netstd_doc(out, tservice); if (is_wcf_enabled()) { - out << indent() << "[ServiceContract(Namespace=\"" << wcf_namespace_ << "\")]" << endl; + out << indent() << "[ServiceContract(Namespace=\"" << wcf_namespace_ << "\")]" << '\n'; } + generate_deprecation_attribute(out, tservice->annotations_); prepare_member_name_mapping(tservice); - out << indent() << "public interface IAsync" << extends_iface << endl - << indent() << "{" << endl; + out << indent() << "public interface IAsync" << extends_iface << '\n' + << indent() << "{" << '\n'; indent_up(); vector functions = tservice->get_functions(); @@ -1993,34 +2126,42 @@ void t_netstd_generator::generate_service_interface(ostream& out, t_service* tse // if we're using WCF, add the corresponding attributes if (is_wcf_enabled()) { - out << indent() << "[OperationContract]" << endl; + out << indent() << "[OperationContract]" << '\n'; const vector& xceptions = (*f_iter)->get_xceptions()->get_members(); vector::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() << "[FaultContract(typeof(" + type_name((*x_iter)->get_type()) + "Fault))]" << '\n'; } } - generate_deprecation_attribute(out, *f_iter); - out << indent() << function_signature_async(*f_iter) << ";" << endl << endl; + generate_deprecation_attribute(out, (*f_iter)->annotations_); + out << indent() << function_signature_async(*f_iter) << ";" << '\n' << '\n'; } indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; cleanup_member_name_mapping(tservice); } -void t_netstd_generator::generate_deprecation_attribute(ostream& out, t_function* func) +bool t_netstd_generator::is_deprecated(std::map>& annotations) { - auto iter = func->annotations_.find("deprecated"); - if( func->annotations_.end() != iter) { + auto iter = annotations.find("deprecated"); + return (annotations.end() != iter); +} + +void t_netstd_generator::generate_deprecation_attribute(ostream& out, std::map>& annotations) +{ + auto iter = annotations.find("deprecated"); + if( annotations.end() != iter) { out << indent() << "[Obsolete"; // empty annotation values end up with "1" somewhere, ignore these as well if ((iter->second.back().length() > 0) && (iter->second.back() != "1")) { out << "(" << make_csharp_string_literal(iter->second.back()) << ")"; + } else { + out << "(" << make_csharp_string_literal("This code is deprecated.") << ")"; // generic message to prevent CA1041 } - out << "]" << endl; + out << "]" << '\n'; } } @@ -2030,8 +2171,8 @@ void t_netstd_generator::generate_service_helpers(ostream& out, t_service* tserv vector::iterator f_iter; prepare_member_name_mapping(tservice); - out << indent() << "public class InternalStructs" << endl; - out << indent() << "{" << endl; + out << indent() << "public class InternalStructs" << '\n'; + out << indent() << "{" << '\n'; indent_up(); for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) @@ -2043,7 +2184,7 @@ void t_netstd_generator::generate_service_helpers(ostream& out, t_service* tserv } indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; cleanup_member_name_mapping(tservice); } @@ -2061,22 +2202,23 @@ void t_netstd_generator::generate_service_client(ostream& out, t_service* tservi extends_client = "TBaseClient, IDisposable, "; } - out << endl; + out << '\n'; generate_netstd_doc(out, tservice); + generate_deprecation_attribute(out, tservice->annotations_); prepare_member_name_mapping(tservice); - out << indent() << "public class Client : " << extends_client << "IAsync" << endl - << indent() << "{" << endl; + out << indent() << "public class Client : " << extends_client << "IAsync" << '\n' + << indent() << "{" << '\n'; 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)" << endl - << indent() << "{" << endl - << indent() << "}" << endl - << endl; + out << indent() << "public Client(TProtocol protocol) : this(protocol, protocol)" << '\n' + << indent() << "{" << '\n' + << indent() << "}" << '\n' + << '\n' + << indent() << "public Client(TProtocol inputProtocol, TProtocol outputProtocol) : base(inputProtocol, outputProtocol)" << '\n' + << indent() << "{" << '\n' + << indent() << "}" << '\n' + << '\n'; vector functions = tservice->get_functions(); vector::const_iterator functions_iterator; @@ -2087,27 +2229,27 @@ void t_netstd_generator::generate_service_client(ostream& out, t_service* tservi string function_name = raw_func_name + (add_async_postfix ? "Async" : ""); // async - generate_deprecation_attribute(out, *functions_iterator); - out << indent() << "public async " << function_signature_async(*functions_iterator, "") << endl - << indent() << "{" << endl; + generate_deprecation_attribute(out, (*functions_iterator)->annotations_); + out << indent() << "public async " << function_signature_async(*functions_iterator, "") << '\n' + << indent() << "{" << '\n'; indent_up(); out << indent() << "await send_" << function_name << "("; string call_args = argument_list((*functions_iterator)->get_arglist(),false); if(! call_args.empty()) { out << call_args << ", "; } - out << CANCELLATION_TOKEN_NAME << ");" << endl; + out << CANCELLATION_TOKEN_NAME << ");" << '\n'; if(! (*functions_iterator)->is_oneway()) { out << indent() << ((*functions_iterator)->get_returntype()->is_void() ? "" : "return ") - << "await recv_" << function_name << "(" << CANCELLATION_TOKEN_NAME << ");" << endl; + << "await recv_" << function_name << "(" << CANCELLATION_TOKEN_NAME << ");" << '\n'; } indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; // async send - generate_deprecation_attribute(out, *functions_iterator); - out << indent() << "public async " << function_signature_async(*functions_iterator, "send_", MODE_NO_RETURN) << endl - << indent() << "{" << endl; + generate_deprecation_attribute(out, (*functions_iterator)->annotations_); + out << indent() << "public async " << function_signature_async(*functions_iterator, "send_", MODE_NO_RETURN) << '\n' + << indent() << "{" << '\n'; indent_up(); string tmpvar = tmp("tmp"); @@ -2115,9 +2257,9 @@ void t_netstd_generator::generate_service_client(ostream& out, t_service* tservi out << indent() << "await OutputProtocol.WriteMessageBeginAsync(new TMessage(\"" << raw_func_name << "\", TMessageType." << ((*functions_iterator)->is_oneway() ? "Oneway" : "Call") - << ", SeqId), " << CANCELLATION_TOKEN_NAME << ");" << endl - << indent() << endl - << indent() << "var " << tmpvar << " = new InternalStructs." << argsname << "() {" << endl; + << ", SeqId), " << CANCELLATION_TOKEN_NAME << ");" << '\n' + << indent() << '\n' + << indent() << "var " << tmpvar << " = new InternalStructs." << argsname << "() {" << '\n'; indent_up(); t_struct* arg_struct = (*functions_iterator)->get_arglist(); @@ -2128,27 +2270,27 @@ void t_netstd_generator::generate_service_client(ostream& out, t_service* tservi for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) { - out << indent() << prop_name(*fld_iter) << " = " << normalize_name((*fld_iter)->get_name(),true) << "," << endl; + out << indent() << prop_name(*fld_iter) << " = " << normalize_name((*fld_iter)->get_name(),true) << "," << '\n'; } indent_down(); - out << indent() << "};" << endl; + out << indent() << "};" << '\n'; - out << indent() << endl - << indent() << "await " << tmpvar << ".WriteAsync(OutputProtocol, " << CANCELLATION_TOKEN_NAME << ");" << endl - << indent() << "await OutputProtocol.WriteMessageEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl - << indent() << "await OutputProtocol.Transport.FlushAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << '\n' + << indent() << "await " << tmpvar << ".WriteAsync(OutputProtocol, " << CANCELLATION_TOKEN_NAME << ");" << '\n' + << indent() << "await OutputProtocol.WriteMessageEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n' + << indent() << "await OutputProtocol.Transport.FlushAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; if (!(*functions_iterator)->is_oneway()) { // async recv - generate_deprecation_attribute(out, *functions_iterator); - out << indent() << "public async " << function_signature_async(*functions_iterator, "recv_", MODE_NO_ARGS) << endl - << indent() << "{" << endl; + generate_deprecation_attribute(out, (*functions_iterator)->annotations_); + out << indent() << "public async " << function_signature_async(*functions_iterator, "recv_", MODE_NO_ARGS) << '\n' + << indent() << "{" << '\n'; indent_up(); string resultname = (*functions_iterator)->get_name() + "_result"; @@ -2158,64 +2300,64 @@ void t_netstd_generator::generate_service_client(ostream& out, t_service* tservi prepare_member_name_mapping(xs, xs->get_members(), resultname); tmpvar = tmp("tmp"); - out << indent() << endl - << indent() << "var " << tmpvar << " = await InputProtocol.ReadMessageBeginAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl - << indent() << "if (" << tmpvar << ".Type == TMessageType.Exception)" << endl - << indent() << "{" << endl; + out << indent() << '\n' + << indent() << "var " << tmpvar << " = await InputProtocol.ReadMessageBeginAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n' + << indent() << "if (" << tmpvar << ".Type == TMessageType.Exception)" << '\n' + << indent() << "{" << '\n'; indent_up(); tmpvar = tmp("tmp"); - out << indent() << "var " << tmpvar << " = await TApplicationException.ReadAsync(InputProtocol, " << CANCELLATION_TOKEN_NAME << ");" << endl - << indent() << "await InputProtocol.ReadMessageEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl - << indent() << "throw " << tmpvar << ";" << endl; + out << indent() << "var " << tmpvar << " = await TApplicationException.ReadAsync(InputProtocol, " << CANCELLATION_TOKEN_NAME << ");" << '\n' + << indent() << "await InputProtocol.ReadMessageEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n' + << indent() << "throw " << tmpvar << ";" << '\n'; indent_down(); tmpvar = tmp("tmp"); - out << indent() << "}" << endl - << endl - << indent() << "var " << tmpvar << " = new InternalStructs." << resultname << "();" << endl - << indent() << "await " << tmpvar << ".ReadAsync(InputProtocol, " << CANCELLATION_TOKEN_NAME << ");" << endl - << indent() << "await InputProtocol.ReadMessageEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << "}" << '\n' + << '\n' + << indent() << "var " << tmpvar << " = new InternalStructs." << resultname << "();" << '\n' + << indent() << "await " << tmpvar << ".ReadAsync(InputProtocol, " << CANCELLATION_TOKEN_NAME << ");" << '\n' + << indent() << "await InputProtocol.ReadMessageEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n'; if (!(*functions_iterator)->get_returntype()->is_void()) { - out << indent() << "if (" << tmpvar << ".__isset.success)" << endl - << indent() << "{" << endl; + out << indent() << "if (" << tmpvar << ".__isset.success)" << '\n' + << indent() << "{" << '\n'; indent_up(); string nullable_value = nullable_value_access((*functions_iterator)->get_returntype()); - out << indent() << "return " << tmpvar << ".Success" << nullable_value << ";" << endl; + out << indent() << "return " << tmpvar << ".Success" << nullable_value << ";" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } const vector& xceptions = xs->get_members(); vector::const_iterator x_iter; for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { - out << indent() << "if (" << tmpvar << ".__isset." << get_isset_name(normalize_name((*x_iter)->get_name())) << ")" << endl - << indent() << "{" << endl; + out << indent() << "if (" << tmpvar << ".__isset." << get_isset_name(normalize_name((*x_iter)->get_name())) << ")" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "throw " << tmpvar << "." << prop_name(*x_iter) << nullable_value_access((*x_iter)->get_type()) << ";" << endl; + out << indent() << "throw " << tmpvar << "." << prop_name(*x_iter) << nullable_value_access((*x_iter)->get_type()) << ";" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } if (!(*functions_iterator)->get_returntype()->is_void()) { out << indent() << "throw new TApplicationException(TApplicationException.ExceptionType.MissingResult, \"" - << function_name << " failed: unknown result\");" << endl; + << function_name << " failed: unknown result\");" << '\n'; } cleanup_member_name_mapping(xs); indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } cleanup_member_name_mapping(arg_struct); } indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; cleanup_member_name_mapping(tservice); } @@ -2233,14 +2375,14 @@ void t_netstd_generator::generate_service_server(ostream& out, t_service* tservi } prepare_member_name_mapping(tservice); - out << indent() << "public class AsyncProcessor : " << extends_processor << "ITAsyncProcessor" << endl - << indent() << "{" << endl; + out << indent() << "public class AsyncProcessor : " << extends_processor << "ITAsyncProcessor" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "private readonly IAsync _iAsync;" << endl - << indent() << "private readonly ILogger" << nullable_suffix() << " _logger;" << endl - << endl + out << indent() << "private readonly IAsync _iAsync;" << '\n' + << indent() << "private readonly ILogger" << nullable_suffix() << " _logger;" << '\n' + << '\n' << indent() << "public AsyncProcessor(IAsync iAsync, ILogger" << nullable_suffix() << " logger = default)"; if (!extends.empty()) @@ -2248,101 +2390,101 @@ void t_netstd_generator::generate_service_server(ostream& out, t_service* tservi out << " : base(iAsync)"; } - out << endl - << indent() << "{" << endl; + out << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "_iAsync = iAsync ?? throw new ArgumentNullException(nameof(iAsync));" << endl; - out << indent() << "_logger = logger;" << endl; + out << indent() << "_iAsync = iAsync ?? throw new ArgumentNullException(nameof(iAsync));" << '\n'; + out << indent() << "_logger = logger;" << '\n'; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { string raw_func_name = (*f_iter)->get_name(); - out << indent() << "processMap_[\"" << raw_func_name << "\"] = " << raw_func_name << "_ProcessAsync;" << endl; + out << indent() << "processMap_[\"" << raw_func_name << "\"] = " << raw_func_name << "_ProcessAsync;" << '\n'; } indent_down(); - out << indent() << "}" << endl - << endl; + out << indent() << "}" << '\n' + << '\n'; if (extends.empty()) { - out << indent() << "protected delegate global::System.Threading.Tasks.Task ProcessFunction(int seqid, TProtocol iprot, TProtocol oprot, CancellationToken " << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << "protected delegate global::System.Threading.Tasks.Task ProcessFunction(int seqid, TProtocol iprot, TProtocol oprot, CancellationToken " << CANCELLATION_TOKEN_NAME << ");" << '\n'; } if (extends.empty()) { out << indent() << "protected Dictionary processMap_ = "; if(target_net_version >= 8) { - out << "[];" << endl; + out << "[];" << '\n'; } else if(target_net_version >= 6) { - out << "new();" << endl; + out << "new();" << '\n'; } else { - out << "new Dictionary();" << endl; + out << "new Dictionary();" << '\n'; } } - out << endl; + out << '\n'; if (extends.empty()) { - out << indent() << "public async Task ProcessAsync(TProtocol iprot, TProtocol oprot)" << endl - << indent() << "{" << endl; + out << indent() << "public async Task ProcessAsync(TProtocol iprot, TProtocol oprot)" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "return await ProcessAsync(iprot, oprot, CancellationToken.None);" << endl; + out << indent() << "return await ProcessAsync(iprot, oprot, CancellationToken.None);" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; - out << indent() << "public async Task ProcessAsync(TProtocol iprot, TProtocol oprot, CancellationToken " << CANCELLATION_TOKEN_NAME << ")" << endl; + out << indent() << "public async Task ProcessAsync(TProtocol iprot, TProtocol oprot, CancellationToken " << CANCELLATION_TOKEN_NAME << ")" << '\n'; } else { - out << indent() << "public new async Task ProcessAsync(TProtocol iprot, TProtocol oprot)" << endl - << indent() << "{" << endl; + out << indent() << "public new async Task ProcessAsync(TProtocol iprot, TProtocol oprot)" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "return await ProcessAsync(iprot, oprot, CancellationToken.None);" << endl; + out << indent() << "return await ProcessAsync(iprot, oprot, CancellationToken.None);" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; - out << indent() << "public new async Task ProcessAsync(TProtocol iprot, TProtocol oprot, CancellationToken " << CANCELLATION_TOKEN_NAME << ")" << endl; + out << indent() << "public new async Task ProcessAsync(TProtocol iprot, TProtocol oprot, CancellationToken " << CANCELLATION_TOKEN_NAME << ")" << '\n'; } - out << indent() << "{" << endl; + out << indent() << "{" << '\n'; indent_up(); - out << indent() << "try" << endl - << indent() << "{" << endl; + out << indent() << "try" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "var msg = await iprot.ReadMessageBeginAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl - << endl - << indent() << "processMap_.TryGetValue(msg.Name, out var fn);" << endl - << endl - << indent() << "if (fn == null)" << endl - << indent() << "{" << endl; + out << indent() << "var msg = await iprot.ReadMessageBeginAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n' + << '\n' + << indent() << "processMap_.TryGetValue(msg.Name, out var fn);" << '\n' + << '\n' + << indent() << "if (fn == null)" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "await TProtocolUtil.SkipAsync(iprot, TType.Struct, " << CANCELLATION_TOKEN_NAME << ");" << endl - << indent() << "await iprot.ReadMessageEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << 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), " << CANCELLATION_TOKEN_NAME << ");" << endl - << indent() << "await x.WriteAsync(oprot, " << CANCELLATION_TOKEN_NAME << ");" << endl - << indent() << "await oprot.WriteMessageEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl - << indent() << "await oprot.Transport.FlushAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl - << indent() << "return true;" << endl; + out << indent() << "await TProtocolUtil.SkipAsync(iprot, TType.Struct, " << CANCELLATION_TOKEN_NAME << ");" << '\n' + << indent() << "await iprot.ReadMessageEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n' + << indent() << "var x = new TApplicationException (TApplicationException.ExceptionType.UnknownMethod, \"Invalid method name: '\" + msg.Name + \"'\");" << '\n' + << indent() << "await oprot.WriteMessageBeginAsync(new TMessage(msg.Name, TMessageType.Exception, msg.SeqID), " << CANCELLATION_TOKEN_NAME << ");" << '\n' + << indent() << "await x.WriteAsync(oprot, " << CANCELLATION_TOKEN_NAME << ");" << '\n' + << indent() << "await oprot.WriteMessageEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n' + << indent() << "await oprot.Transport.FlushAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n' + << indent() << "return true;" << '\n'; indent_down(); - out << indent() << "}" << endl - << endl - << indent() << "await fn(msg.SeqID, iprot, oprot, " << CANCELLATION_TOKEN_NAME << ");" << endl - << endl; + out << indent() << "}" << '\n' + << '\n' + << indent() << "await fn(msg.SeqID, iprot, oprot, " << CANCELLATION_TOKEN_NAME << ");" << '\n' + << '\n'; indent_down(); - out << indent() << "}" << endl; - out << indent() << "catch (IOException)" << endl - << indent() << "{" << endl; + out << indent() << "}" << '\n'; + out << indent() << "catch (IOException)" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "return false;" << endl; + out << indent() << "return false;" << '\n'; indent_down(); - out << indent() << "}" << endl - << endl - << indent() << "return true;" << endl; + out << indent() << "}" << '\n' + << '\n' + << indent() << "return true;" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { @@ -2350,7 +2492,7 @@ void t_netstd_generator::generate_service_server(ostream& out, t_service* tservi } indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; cleanup_member_name_mapping(tservice); } @@ -2384,26 +2526,26 @@ void t_netstd_generator::generate_process_function_async(ostream& out, t_service { (void)tservice; out << indent() << "public async global::System.Threading.Tasks.Task " << tfunction->get_name() - << "_ProcessAsync(int seqid, TProtocol iprot, TProtocol oprot, CancellationToken " << CANCELLATION_TOKEN_NAME << ")" << endl - << indent() << "{" << endl; + << "_ProcessAsync(int seqid, TProtocol iprot, TProtocol oprot, CancellationToken " << CANCELLATION_TOKEN_NAME << ")" << '\n' + << indent() << "{" << '\n'; indent_up(); string argsname = tfunction->get_name() + "_args"; string resultname = tfunction->get_name() + "_result"; string args = tmp("tmp"); - out << indent() << "var " << args << " = new InternalStructs." << argsname << "();" << endl - << indent() << "await " << args << ".ReadAsync(iprot, " << CANCELLATION_TOKEN_NAME << ");" << endl - << indent() << "await iprot.ReadMessageEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << "var " << args << " = new InternalStructs." << argsname << "();" << '\n' + << indent() << "await " << args << ".ReadAsync(iprot, " << CANCELLATION_TOKEN_NAME << ");" << '\n' + << indent() << "await iprot.ReadMessageEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n'; string tmpResult = tmp("tmp"); if (!tfunction->is_oneway()) { - out << indent() << "var " << tmpResult << " = new InternalStructs." << resultname << "();" << endl; + out << indent() << "var " << tmpResult << " = new InternalStructs." << resultname << "();" << '\n'; } - out << indent() << "try" << endl - << indent() << "{" << endl; + out << indent() << "try" << '\n' + << indent() << "{" << '\n'; indent_up(); t_struct* xs = tfunction->get_xceptions(); @@ -2411,8 +2553,8 @@ void t_netstd_generator::generate_process_function_async(ostream& out, t_service if (xceptions.size() > 0) { - out << indent() << "try" << endl - << indent() << "{" << endl; + out << indent() << "try" << '\n' + << indent() << "{" << '\n'; indent_up(); } @@ -2420,9 +2562,8 @@ void t_netstd_generator::generate_process_function_async(ostream& out, t_service const vector& fields = arg_struct->get_members(); vector::const_iterator f_iter; - bool is_deprecated = (tfunction->annotations_.end() != tfunction->annotations_.find("deprecated")); - if( is_deprecated) { - out << indent() << "#pragma warning disable CS0618,CS0612" << endl; + if( is_deprecated(tfunction->annotations_)) { + out << indent() << "#pragma warning disable CS0618,CS0612" << '\n'; } out << indent(); @@ -2457,10 +2598,10 @@ void t_netstd_generator::generate_process_function_async(ostream& out, t_service out << ", "; } - out << "" << CANCELLATION_TOKEN_NAME << ");" << endl; + out << "" << CANCELLATION_TOKEN_NAME << ");" << '\n'; - if( is_deprecated) { - out << indent() << "#pragma warning restore CS0618,CS0612" << endl; + if( is_deprecated(tfunction->annotations_)) { + out << indent() << "#pragma warning restore CS0618,CS0612" << '\n'; } vector::const_iterator x_iter; @@ -2470,76 +2611,76 @@ void t_netstd_generator::generate_process_function_async(ostream& out, t_service if (xceptions.size() > 0) { indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { string tmpex = tmp("tmp"); - out << indent() << "catch (" << type_name((*x_iter)->get_type()) << " " << tmpex << ")" << endl - << indent() << "{" << endl; + out << indent() << "catch (" << type_name((*x_iter)->get_type()) << " " << tmpex << ")" << '\n' + << indent() << "{" << '\n'; if (!tfunction->is_oneway()) { indent_up(); - out << indent() << tmpResult << "." << prop_name(*x_iter) << " = " << tmpex << ";" << endl; + out << indent() << tmpResult << "." << prop_name(*x_iter) << " = " << tmpex << ";" << '\n'; indent_down(); } - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } } if (!tfunction->is_oneway()) { out << indent() << "await oprot.WriteMessageBeginAsync(new TMessage(\"" - << tfunction->get_name() << "\", TMessageType.Reply, seqid), " << CANCELLATION_TOKEN_NAME << "); " << endl - << indent() << "await " << tmpResult << ".WriteAsync(oprot, " << CANCELLATION_TOKEN_NAME << ");" << endl; + << tfunction->get_name() << "\", TMessageType.Reply, seqid), " << CANCELLATION_TOKEN_NAME << "); " << '\n' + << indent() << "await " << tmpResult << ".WriteAsync(oprot, " << CANCELLATION_TOKEN_NAME << ");" << '\n'; } indent_down(); cleanup_member_name_mapping(xs); string tmpex = tmp("tmp"); - out << indent() << "}" << endl - << indent() << "catch (TTransportException)" << endl - << indent() << "{" << endl - << indent() << " throw;" << endl - << indent() << "}" << endl - << indent() << "catch (Exception " << tmpex << ")" << endl - << indent() << "{" << endl; + out << indent() << "}" << '\n' + << indent() << "catch (TTransportException)" << '\n' + << indent() << "{" << '\n' + << indent() << " throw;" << '\n' + << indent() << "}" << '\n' + << indent() << "catch (Exception " << tmpex << ")" << '\n' + << indent() << "{" << '\n'; indent_up(); string tmpvar = tmp("tmp"); - out << indent() << "var " << tmpvar << " = $\"Error occurred in {GetType().FullName}: {" << tmpex << ".Message}\";" << endl; - out << indent() << "if(_logger != null)" << endl; + out << indent() << "var " << tmpvar << " = $\"Error occurred in {GetType().FullName}: {" << tmpex << ".Message}\";" << '\n'; + out << indent() << "if(_logger != null)" << '\n'; indent_up(); - out << indent() << "_logger.LogError(\"{Exception}, {Message}\", " << tmpex << ", " << tmpvar << ");" << endl; + out << indent() << "_logger.LogError(\"{Exception}, {Message}\", " << tmpex << ", " << tmpvar << ");" << '\n'; indent_down(); - out << indent() << "else" << endl; + out << indent() << "else" << '\n'; indent_up(); - out << indent() << "Console.Error.WriteLine(" << tmpvar << ");" << endl; + out << indent() << "Console.Error.WriteLine(" << tmpvar << ");" << '\n'; indent_down(); if (tfunction->is_oneway()) { indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } else { tmpvar = tmp("tmp"); - out << indent() << "var " << tmpvar << " = new TApplicationException(TApplicationException.ExceptionType.InternalError,\" Internal error.\");" << endl + out << indent() << "var " << tmpvar << " = new TApplicationException(TApplicationException.ExceptionType.InternalError,\" Internal error.\");" << '\n' << indent() << "await oprot.WriteMessageBeginAsync(new TMessage(\"" << tfunction->get_name() - << "\", TMessageType.Exception, seqid), " << CANCELLATION_TOKEN_NAME << ");" << endl - << indent() << "await " << tmpvar << ".WriteAsync(oprot, " << CANCELLATION_TOKEN_NAME << ");" << endl; + << "\", TMessageType.Exception, seqid), " << CANCELLATION_TOKEN_NAME << ");" << '\n' + << indent() << "await " << tmpvar << ".WriteAsync(oprot, " << CANCELLATION_TOKEN_NAME << ");" << '\n'; indent_down(); - out << indent() << "}" << endl - << indent() << "await oprot.WriteMessageEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl - << indent() << "await oprot.Transport.FlushAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << "}" << '\n' + << indent() << "await oprot.WriteMessageEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n' + << indent() << "await oprot.Transport.FlushAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n'; } indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } void t_netstd_generator::generate_netstd_union_reader(ostream& out, t_struct* tunion) @@ -2548,76 +2689,76 @@ void t_netstd_generator::generate_netstd_union_reader(ostream& out, t_struct* tu const vector& fields = tunion->get_members(); vector::const_iterator f_iter; - out << indent() << "public static async Task<" << tunion->get_name() << "> ReadAsync(TProtocol iprot, CancellationToken " << CANCELLATION_TOKEN_NAME << ")" << endl; + out << indent() << "public static async Task<" << tunion->get_name() << "> ReadAsync(TProtocol iprot, CancellationToken " << CANCELLATION_TOKEN_NAME << ")" << '\n'; scope_up(out); - out << indent() << "iprot.IncrementRecursionDepth();" << endl; - out << indent() << "try" << endl; + out << indent() << "iprot.IncrementRecursionDepth();" << '\n'; + out << indent() << "try" << '\n'; scope_up(out); string tmpRetval = tmp("tmp"); - out << indent() << tunion->get_name() << " " << tmpRetval << ";" << endl; - out << indent() << "await iprot.ReadStructBeginAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl; - out << indent() << "TField field = await iprot.ReadFieldBeginAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << tunion->get_name() << " " << tmpRetval << ";" << '\n'; + out << indent() << "await iprot.ReadStructBeginAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n'; + out << indent() << "TField field = await iprot.ReadFieldBeginAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n'; // we cannot have the first field be a stop -- we must have a single field defined - out << indent() << "if (field.Type == TType.Stop)" << endl; + out << indent() << "if (field.Type == TType.Stop)" << '\n'; scope_up(out); - out << indent() << "await iprot.ReadFieldEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl; - out << indent() << "" << tmpRetval << " = new ___undefined();" << endl; + out << indent() << "await iprot.ReadFieldEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n'; + out << indent() << "" << tmpRetval << " = new ___undefined();" << '\n'; scope_down(out); - out << indent() << "else" << endl; + out << indent() << "else" << '\n'; scope_up(out); - out << indent() << "switch (field.ID)" << endl; + out << indent() << "switch (field.ID)" << '\n'; scope_up(out); for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { - out << indent() << "case " << (*f_iter)->get_key() << ":" << endl; + out << indent() << "case " << (*f_iter)->get_key() << ":" << '\n'; indent_up(); - out << indent() << "if (field.Type == " << type_to_enum((*f_iter)->get_type()) << ") {" << endl; + out << indent() << "if (field.Type == " << type_to_enum((*f_iter)->get_type()) << ") {" << '\n'; indent_up(); string tmpvar = tmp("tmp"); - out << indent() << type_name((*f_iter)->get_type()) << " " << tmpvar << ";" << endl; + out << indent() << type_name((*f_iter)->get_type()) << " " << tmpvar << ";" << '\n'; generate_deserialize_field(out, (*f_iter), tmpvar, true); - out << indent() << tmpRetval << " = new " << (*f_iter)->get_name() << "(" << tmpvar << ");" << endl; + out << indent() << tmpRetval << " = new " << (*f_iter)->get_name() << "(" << tmpvar << ");" << '\n'; indent_down(); - out << indent() << "} else { " << endl << indent() << " await TProtocolUtil.SkipAsync(iprot, field.Type, " << CANCELLATION_TOKEN_NAME << ");" - << endl << indent() << " " << tmpRetval << " = new ___undefined();" << endl << indent() << "}" << endl - << indent() << "break;" << endl; + out << indent() << "} else { " << '\n' << indent() << " await TProtocolUtil.SkipAsync(iprot, field.Type, " << CANCELLATION_TOKEN_NAME << ");" + << '\n' << indent() << " " << tmpRetval << " = new ___undefined();" << '\n' << indent() << "}" << '\n' + << indent() << "break;" << '\n'; indent_down(); } - out << indent() << "default: " << endl; + out << indent() << "default: " << '\n'; indent_up(); - out << indent() << "await TProtocolUtil.SkipAsync(iprot, field.Type, " << CANCELLATION_TOKEN_NAME << ");" << endl << indent() - << tmpRetval << " = new ___undefined();" << endl; - out << indent() << "break;" << endl; + out << indent() << "await TProtocolUtil.SkipAsync(iprot, field.Type, " << CANCELLATION_TOKEN_NAME << ");" << '\n' << indent() + << tmpRetval << " = new ___undefined();" << '\n'; + out << indent() << "break;" << '\n'; indent_down(); scope_down(out); - out << indent() << "await iprot.ReadFieldEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << "await iprot.ReadFieldEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n'; - out << indent() << "if ((await iprot.ReadFieldBeginAsync(" << CANCELLATION_TOKEN_NAME << ")).Type != TType.Stop)" << endl; + out << indent() << "if ((await iprot.ReadFieldBeginAsync(" << CANCELLATION_TOKEN_NAME << ")).Type != TType.Stop)" << '\n'; scope_up(out); - out << indent() << "throw new TProtocolException(TProtocolException.INVALID_DATA);" << endl; + out << indent() << "throw new TProtocolException(TProtocolException.INVALID_DATA);" << '\n'; scope_down(out); // end of else for TStop scope_down(out); - out << indent() << "await iprot.ReadStructEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl; - out << indent() << "return " << tmpRetval << ";" << endl; + out << indent() << "await iprot.ReadStructEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n'; + out << indent() << "return " << tmpRetval << ";" << '\n'; indent_down(); scope_down(out); - out << indent() << "finally" << endl; + out << indent() << "finally" << '\n'; scope_up(out); - out << indent() << "iprot.DecrementRecursionDepth();" << endl; + out << indent() << "iprot.DecrementRecursionDepth();" << '\n'; scope_down(out); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } void t_netstd_generator::generate_deserialize_field(ostream& out, t_field* tfield, string prefix, bool is_propertyless) @@ -2698,7 +2839,7 @@ void t_netstd_generator::generate_deserialize_field(ostream& out, t_field* tfiel { out << "ReadI32Async(" << CANCELLATION_TOKEN_NAME << ");"; } - out << endl; + out << '\n'; } else { @@ -2710,18 +2851,18 @@ void t_netstd_generator::generate_deserialize_struct(ostream& out, t_struct* tst { if (is_union_enabled() && tstruct->is_union()) { - out << indent() << prefix << " = await " << type_name(tstruct) << ".ReadAsync(iprot, " << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << prefix << " = await " << type_name(tstruct) << ".ReadAsync(iprot, " << CANCELLATION_TOKEN_NAME << ");" << '\n'; } else { - out << indent() << prefix << " = new " << type_name(tstruct) << "();" << endl - << indent() << "await " << prefix << ".ReadAsync(iprot, " << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << prefix << " = new " << type_name(tstruct) << "();" << '\n' + << indent() << "await " << prefix << ".ReadAsync(iprot, " << CANCELLATION_TOKEN_NAME << ");" << '\n'; } } void t_netstd_generator::generate_deserialize_container(ostream& out, t_type* ttype, string prefix) { - out << indent() << "{" << endl; + out << indent() << "{" << '\n'; indent_up(); string obj; @@ -2741,21 +2882,25 @@ void t_netstd_generator::generate_deserialize_container(ostream& out, t_type* tt if (ttype->is_map()) { - out << indent() << "var " << obj << " = await iprot.ReadMapBeginAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << "var " << obj << " = await iprot.ReadMapBeginAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n'; } else if (ttype->is_set()) { - out << indent() << "var " << obj << " = await iprot.ReadSetBeginAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << "var " << obj << " = await iprot.ReadSetBeginAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n'; } else if (ttype->is_list()) { - out << indent() << "var " << obj << " = await iprot.ReadListBeginAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << "var " << obj << " = await iprot.ReadListBeginAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n'; } - out << indent() << prefix << " = new " << type_name(ttype) << "(" << obj << ".Count);" << endl; + if( (target_net_version < 5) && ttype->is_set()) { + out << indent() << prefix << " = new " << type_name(ttype) << "();" << '\n'; + } else { + out << indent() << prefix << " = new " << type_name(ttype) << "(" << obj << ".Count);" << '\n'; + } string i = tmp("_i"); - out << indent() << "for(int " << i << " = 0; " << i << " < " << obj << ".Count; ++" << i << ")" << endl - << indent() << "{" << endl; + out << indent() << "for(int " << i << " = 0; " << i << " < " << obj << ".Count; ++" << i << ")" << '\n' + << indent() << "{" << '\n'; indent_up(); if (ttype->is_map()) @@ -2772,23 +2917,23 @@ void t_netstd_generator::generate_deserialize_container(ostream& out, t_type* tt } indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; if (ttype->is_map()) { - out << indent() << "await iprot.ReadMapEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << "await iprot.ReadMapEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n'; } else if (ttype->is_set()) { - out << indent() << "await iprot.ReadSetEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << "await iprot.ReadSetEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n'; } else if (ttype->is_list()) { - out << indent() << "await iprot.ReadListEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << "await iprot.ReadListEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n'; } indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } void t_netstd_generator::generate_deserialize_map_element(ostream& out, t_map* tmap, string prefix) @@ -2799,13 +2944,13 @@ void t_netstd_generator::generate_deserialize_map_element(ostream& out, t_map* t t_field fkey(tmap->get_key_type(), key); t_field fval(tmap->get_val_type(), val); - out << indent() << declare_field(&fkey, false, false) << endl; - out << indent() << declare_field(&fval, false, false) << endl; + out << indent() << declare_field(&fkey, false, false) << '\n'; + out << indent() << declare_field(&fval, false, false) << '\n'; generate_deserialize_field(out, &fkey); generate_deserialize_field(out, &fval); - out << indent() << prefix << "[" << key << "] = " << val << ";" << endl; + out << indent() << prefix << "[" << key << "] = " << val << ";" << '\n'; } void t_netstd_generator::generate_deserialize_set_element(ostream& out, t_set* tset, string prefix) @@ -2813,11 +2958,11 @@ void t_netstd_generator::generate_deserialize_set_element(ostream& out, t_set* t string elem = tmp("_elem"); t_field felem(tset->get_elem_type(), elem); - out << indent() << declare_field(&felem, false, false) << endl; + out << indent() << declare_field(&felem, false, false) << '\n'; generate_deserialize_field(out, &felem); - out << indent() << prefix << ".Add(" << elem << ");" << endl; + out << indent() << prefix << ".Add(" << elem << ");" << '\n'; } void t_netstd_generator::generate_deserialize_list_element(ostream& out, t_list* tlist, string prefix) @@ -2825,11 +2970,11 @@ void t_netstd_generator::generate_deserialize_list_element(ostream& out, t_list* string elem = tmp("_elem"); t_field felem(tlist->get_elem_type(), elem); - out << indent() << declare_field(&felem, false, false) << endl; + out << indent() << declare_field(&felem, false, false) << '\n'; generate_deserialize_field(out, &felem); - out << indent() << prefix << ".Add(" << elem << ");" << endl; + out << indent() << prefix << ".Add(" << elem << ");" << '\n'; } void t_netstd_generator::generate_serialize_field(ostream& out, t_field* tfield, string prefix, bool is_propertyless, bool allow_nullable) @@ -2904,7 +3049,7 @@ void t_netstd_generator::generate_serialize_field(ostream& out, t_field* tfield, { out << "WriteI32Async((int)" << name << ", " << CANCELLATION_TOKEN_NAME << ");"; } - out << endl; + out << '\n'; } else { @@ -2915,7 +3060,7 @@ void t_netstd_generator::generate_serialize_field(ostream& out, t_field* tfield, void t_netstd_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix) { (void)tstruct; - out << indent() << "await " << prefix << ".WriteAsync(oprot, " << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << "await " << prefix << ".WriteAsync(oprot, " << CANCELLATION_TOKEN_NAME << ");" << '\n'; } void t_netstd_generator::generate_serialize_container(ostream& out, t_type* ttype, string prefix) @@ -2924,18 +3069,18 @@ void t_netstd_generator::generate_serialize_container(ostream& out, t_type* ttyp { out << indent() << "await oprot.WriteMapBeginAsync(new TMap(" << type_to_enum(static_cast(ttype)->get_key_type()) << ", " << type_to_enum(static_cast(ttype)->get_val_type()) << ", " << prefix - << ".Count), " << CANCELLATION_TOKEN_NAME << ");" << endl; + << ".Count), " << CANCELLATION_TOKEN_NAME << ");" << '\n'; } else if (ttype->is_set()) { out << indent() << "await oprot.WriteSetBeginAsync(new TSet(" << type_to_enum(static_cast(ttype)->get_elem_type()) - << ", " << prefix << ".Count), " << CANCELLATION_TOKEN_NAME << ");" << endl; + << ", " << prefix << ".Count), " << CANCELLATION_TOKEN_NAME << ");" << '\n'; } else if (ttype->is_list()) { out << indent() << "await oprot.WriteListBeginAsync(new TList(" << type_to_enum(static_cast(ttype)->get_elem_type()) << ", " << prefix << ".Count), " << CANCELLATION_TOKEN_NAME << ");" - << endl; + << '\n'; } string iter = tmp("_iter"); @@ -2955,8 +3100,8 @@ void t_netstd_generator::generate_serialize_container(ostream& out, t_type* ttyp << " in " << prefix << ")"; } - out << endl; - out << indent() << "{" << endl; + out << '\n'; + out << indent() << "{" << '\n'; indent_up(); if (ttype->is_map()) @@ -2973,19 +3118,19 @@ void t_netstd_generator::generate_serialize_container(ostream& out, t_type* ttyp } indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; if (ttype->is_map()) { - out << indent() << "await oprot.WriteMapEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << "await oprot.WriteMapEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n'; } else if (ttype->is_set()) { - out << indent() << "await oprot.WriteSetEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << "await oprot.WriteSetEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n'; } else if (ttype->is_list()) { - out << indent() << "await oprot.WriteListEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << "await oprot.WriteListEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << '\n'; } } @@ -3018,8 +3163,9 @@ void t_netstd_generator::generate_netstd_property(ostream& out, t_field* tfield, { if ((is_serialize_enabled() || is_wcf_enabled()) && isPublic) { - out << indent() << "[DataMember(Order = 0)]" << endl; + out << indent() << "[DataMember(Order = 0)]" << '\n'; } + generate_deprecation_attribute(out, tfield->annotations_); out << indent() << (isPublic ? "public " : "private ") @@ -3036,37 +3182,37 @@ void t_netstd_generator::generate_netstd_property(ostream& out, t_field* tfield, if( (target_net_version >= 6) && (!force_member_nullable(tfield))) { out << initialize_field(tfield) << ";"; } - out << endl; + out << '\n'; } else { - out << endl - << indent() << "{" << endl; + out << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "get" << endl - << indent() << "{" << endl; + out << indent() << "get" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "return " << fieldPrefix + tfield->get_name() << ";" << endl; + out << indent() << "return " << fieldPrefix + tfield->get_name() << ";" << '\n'; indent_down(); - out << indent() << "}" << endl - << indent() << "set" << endl - << indent() << "{" << endl; + out << indent() << "}" << '\n' + << indent() << "set" << '\n' + << indent() << "{" << '\n'; indent_up(); if (generateIsset) { - out << indent() << "__isset." << get_isset_name(normalize_name(tfield->get_name())) << " = true;" << endl; + out << indent() << "__isset." << get_isset_name(normalize_name(tfield->get_name())) << " = true;" << '\n'; } - out << indent() << "this." << fieldPrefix + tfield->get_name() << " = value;" << endl; + out << indent() << "this." << fieldPrefix + tfield->get_name() << " = value;" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } - out << endl; + out << '\n'; } string t_netstd_generator::make_csharp_string_literal( string const& value) @@ -3749,14 +3895,14 @@ string t_netstd_generator::type_to_enum(t_type* type) void t_netstd_generator::generate_netstd_docstring_comment(ostream& out, string contents) { - docstring_comment(out, "/// " + endl, "/// ", contents, "/// " + endl); + docstring_comment(out, "/// " + string("\n"), "/// ", contents, "/// " + string("\n")); } 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 + "get_type()) + "\"/>"; + string combined_message = field->get_doc() + "\n" + "get_type()) + "\"/>"; generate_netstd_docstring_comment(out, combined_message); } else @@ -3783,7 +3929,7 @@ void t_netstd_generator::generate_netstd_doc(ostream& out, t_function* tfunction for (p_iter = fields.begin(); p_iter != fields.end(); ++p_iter) { t_field* p = *p_iter; - ps << endl << "get_name() << "\">"; + ps << '\n' << "get_name() << "\">"; if (p->has_doc()) { string str = p->get_doc(); @@ -3796,7 +3942,7 @@ void t_netstd_generator::generate_netstd_doc(ostream& out, t_function* tfunction docstring_comment(out, "", "/// ", - "" + endl + tfunction->get_doc() + "" + ps.str(), + "" + string("\n") + tfunction->get_doc() + "" + ps.str(), ""); } } @@ -3818,11 +3964,11 @@ void t_netstd_generator::docstring_comment(ostream& out, const string& comment_s // Just prnt a newline when the line & prefix are empty. if (strlen(line) == 0 && line_prefix == "" && !docs.eof()) { - out << endl; + out << '\n'; } else if (strlen(line) > 0 || !docs.eof()) { // skip the empty last line - out << indent() << line_prefix << line << endl; + out << indent() << line_prefix << line << '\n'; } } if (comment_end != "") @@ -3854,8 +4000,8 @@ THRIFT_REGISTER_GENERATOR( " serial: Add serialization support to generated classes.\n" " union: Use new union typing, which includes a static read function for union types.\n" " pascal: Generate Pascal Case property names according to Microsoft naming convention.\n" - " net6: Enable features that require net6 and C# 8 or higher.\n" " net8: Enable features that require net8 and C# 12 or higher.\n" + " net9: Enable features that require net9 and C# 13 or higher.\n" " no_deepcopy: Suppress generation of " + DEEP_COPY_METHOD_NAME + "() method.\n" " async_postfix: Append \"Async\" to all service methods (maintains compatibility with existing code).\n" ) diff --git a/compiler/cpp/src/thrift/generate/t_netstd_generator.h b/compiler/cpp/src/thrift/generate/t_netstd_generator.h index ff3cfb1264c..4623b122862 100644 --- a/compiler/cpp/src/thrift/generate/t_netstd_generator.h +++ b/compiler/cpp/src/thrift/generate/t_netstd_generator.h @@ -44,8 +44,6 @@ using std::string; using std::stringstream; using std::vector; -static const string endl = "\n"; // avoid ostream << std::endl flushes - static const string DEEP_COPY_METHOD_NAME = "DeepCopy"; static const string CANCELLATION_TOKEN_NAME = "cancellationToken"; @@ -106,7 +104,7 @@ class t_netstd_generator : public t_oop_generator 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_deprecation_attribute(ostream& out, t_function* func); + void generate_deprecation_attribute(ostream& out, std::map>& annotations); 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); @@ -165,7 +163,7 @@ class t_netstd_generator : public t_oop_generator comment += " */\n"; return comment; } - + private: string namespace_name_; @@ -177,20 +175,20 @@ class t_netstd_generator : public t_oop_generator bool wcf_; bool use_pascal_case_properties; bool suppress_deepcopy; - int target_net_version; // 0 = any, 6 = net6, 8 = net8 + int target_net_version; // 0 = any, 6 = net6, 8 = net8, etc. bool add_async_postfix; const std::string CSHARP_KEYWORDS[101] = { // C# keywords - "abstract", "as", "base", "bool", "break", "byte", "case", "catch", "char", "checked", "class", "const", "continue", - "decimal", "default", "delegate", "do", "double", "else", "enum", "event", "explicit", "extern", "false", "finally", - "fixed", "float", "for", "foreach", "goto", "if", "implicit", "in", "int", "interface", "internal", "is", "lock", - "long", "namespace", "new", "null", "object", "operator", "out", "override", "params", "private", "protected", - "public", "readonly", "ref", "return", "sbyte", "sealed", "short", "sizeof", "stackalloc", "static", "string", - "struct", "switch", "this", "throw", "true", "try", "typeof", "uint", "ulong", "unchecked", "unsafe", "ushort", - "using", "virtual", "void", "volatile", "while", + "abstract", "as", "base", "bool", "break", "byte", "case", "catch", "char", "checked", "class", "const", "continue", + "decimal", "default", "delegate", "do", "double", "else", "enum", "event", "explicit", "extern", "false", "finally", + "fixed", "float", "for", "foreach", "goto", "if", "implicit", "in", "int", "interface", "internal", "is", "lock", + "long", "namespace", "new", "null", "object", "operator", "out", "override", "params", "private", "protected", + "public", "readonly", "ref", "return", "sbyte", "sealed", "short", "sizeof", "stackalloc", "static", "string", + "struct", "switch", "this", "throw", "true", "try", "typeof", "uint", "ulong", "unchecked", "unsafe", "ushort", + "using", "virtual", "void", "volatile", "while", // C# contextual keywords - "add", "alias", "ascending", "async", "await", "descending", "dynamic", "from", "get", "global", "group", "into", + "add", "alias", "ascending", "async", "await", "descending", "dynamic", "from", "get", "global", "group", "into", "join", "let", "orderby", "partial", "remove", "select", "set", "value", "var", "when", "where", "yield" }; @@ -199,7 +197,7 @@ class t_netstd_generator : public t_oop_generator vector member_mapping_scopes; map collected_extension_types; map checked_extension_types; - + string normalize_name(string name, bool is_arg_name = false); string make_valid_csharp_identifier(string const& fromName); string make_csharp_string_literal( string const& value); @@ -220,6 +218,8 @@ class t_netstd_generator : public t_oop_generator string initialize_field(t_field* tfield); void pragmas_and_directives(ostream& out); + bool any_deprecations(); + bool is_deprecated(std::map>& annotations); bool is_nullable_type(t_type* ttype); bool force_member_nullable(t_field* tfield); // see there string nullable_suffix(); // unconditionally diff --git a/compiler/cpp/src/thrift/generate/t_ocaml_generator.cc b/compiler/cpp/src/thrift/generate/t_ocaml_generator.cc index 5f9b80cf5ec..34dda402a1a 100644 --- a/compiler/cpp/src/thrift/generate/t_ocaml_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_ocaml_generator.cc @@ -38,8 +38,6 @@ using std::string; using std::stringstream; using std::vector; -static const string endl = "\n"; // avoid ostream << std::endl flushes - /** * OCaml code generator. * @@ -241,10 +239,10 @@ void t_ocaml_generator::init_generator() { f_consts_.open(f_consts_name.c_str()); // Print header - f_types_ << ocaml_autogen_comment() << endl << ocaml_imports() << endl; - f_types_i_ << ocaml_autogen_comment() << endl << ocaml_imports() << endl; - f_consts_ << ocaml_autogen_comment() << endl << ocaml_imports() << endl << "open " - << capitalize(program_name_) << "_types" << endl; + f_types_ << ocaml_autogen_comment() << '\n' << ocaml_imports() << '\n'; + f_types_i_ << ocaml_autogen_comment() << '\n' << ocaml_imports() << '\n'; + f_consts_ << ocaml_autogen_comment() << '\n' << ocaml_imports() << '\n' << "open " + << capitalize(program_name_) << "_types" << '\n'; } /** @@ -277,9 +275,9 @@ t_ocaml_generator::~t_ocaml_generator() { */ void t_ocaml_generator::generate_typedef(t_typedef* ttypedef) { f_types_ << indent() << "type " << decapitalize(ttypedef->get_symbolic()) << " = " - << render_ocaml_type(ttypedef->get_type()) << endl << endl; + << render_ocaml_type(ttypedef->get_type()) << '\n' << '\n'; f_types_i_ << indent() << "type " << decapitalize(ttypedef->get_symbolic()) << " = " - << render_ocaml_type(ttypedef->get_type()) << endl << endl; + << render_ocaml_type(ttypedef->get_type()) << '\n' << '\n'; } /** @@ -289,46 +287,46 @@ void t_ocaml_generator::generate_typedef(t_typedef* ttypedef) { * @param tenum The enumeration */ void t_ocaml_generator::generate_enum(t_enum* tenum) { - indent(f_types_) << "module " << capitalize(tenum->get_name()) << " = " << endl << "struct" - << endl; - indent(f_types_i_) << "module " << capitalize(tenum->get_name()) << " : " << endl << "sig" - << endl; + indent(f_types_) << "module " << capitalize(tenum->get_name()) << " = " << '\n' << "struct" + << '\n'; + indent(f_types_i_) << "module " << capitalize(tenum->get_name()) << " : " << '\n' << "sig" + << '\n'; indent_up(); - indent(f_types_) << "type t = " << endl; - indent(f_types_i_) << "type t = " << endl; + indent(f_types_) << "type t = " << '\n'; + indent(f_types_i_) << "type t = " << '\n'; indent_up(); vector constants = tenum->get_constants(); vector::iterator c_iter; for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) { string name = capitalize((*c_iter)->get_name()); - indent(f_types_) << "| " << name << endl; - indent(f_types_i_) << "| " << name << endl; + indent(f_types_) << "| " << name << '\n'; + indent(f_types_i_) << "| " << name << '\n'; } indent_down(); - indent(f_types_) << "let to_i = function" << endl; - indent(f_types_i_) << "val to_i : t -> Int32.t" << endl; + indent(f_types_) << "let to_i = function" << '\n'; + indent(f_types_i_) << "val to_i : t -> Int32.t" << '\n'; indent_up(); for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) { int value = (*c_iter)->get_value(); string name = capitalize((*c_iter)->get_name()); - indent(f_types_) << "| " << name << " -> " << value << "l" << endl; + indent(f_types_) << "| " << name << " -> " << value << "l" << '\n'; } indent_down(); - indent(f_types_) << "let of_i = function" << endl; - indent(f_types_i_) << "val of_i : Int32.t -> t" << endl; + indent(f_types_) << "let of_i = function" << '\n'; + indent(f_types_i_) << "val of_i : Int32.t -> t" << '\n'; indent_up(); for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) { int value = (*c_iter)->get_value(); string name = capitalize((*c_iter)->get_name()); - indent(f_types_) << "| " << value << "l -> " << name << endl; + indent(f_types_) << "| " << value << "l -> " << name << '\n'; } - indent(f_types_) << "| _ -> raise Thrift_error" << endl; + indent(f_types_) << "| _ -> raise Thrift_error" << '\n'; indent_down(); indent_down(); - indent(f_types_) << "end" << endl; - indent(f_types_i_) << "end" << endl; + indent(f_types_) << "end" << '\n'; + indent(f_types_i_) << "end" << '\n'; } /** @@ -339,7 +337,7 @@ void t_ocaml_generator::generate_const(t_const* tconst) { string name = decapitalize(tconst->get_name()); t_const_value* value = tconst->get_value(); - indent(f_consts_) << "let " << name << " = " << render_const_value(type, value) << endl << endl; + indent(f_consts_) << "let " << name << " = " << render_const_value(type, value) << '\n' << '\n'; } /** @@ -395,9 +393,9 @@ string t_ocaml_generator::render_const_value(t_type* type, t_const_value* value) } else if (type->is_struct() || type->is_xception()) { string cname = type_name(type); string ct = tmp("_c"); - out << endl; + out << '\n'; indent_up(); - indent(out) << "(let " << ct << " = new " << cname << " in" << endl; + indent(out) << "(let " << ct << " = new " << cname << " in" << '\n'; indent_up(); const vector& fields = ((t_struct*)type)->get_members(); vector::const_iterator f_iter; @@ -417,7 +415,7 @@ string t_ocaml_generator::render_const_value(t_type* type, t_const_value* value) out << indent(); out << ct << "#set_" << fname << " "; out << render_const_value(field_type, v_iter->second); - out << ";" << endl; + out << ";" << '\n'; } indent(out) << ct << ")"; indent_down(); @@ -428,14 +426,14 @@ string t_ocaml_generator::render_const_value(t_type* type, t_const_value* value) const map& val = value->get_map(); map::const_iterator v_iter; string hm = tmp("_hm"); - out << endl; + out << '\n'; indent_up(); - indent(out) << "(let " << hm << " = Hashtbl.create " << val.size() << " in" << endl; + indent(out) << "(let " << hm << " = Hashtbl.create " << val.size() << " in" << '\n'; indent_up(); for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { string key = render_const_value(ktype, v_iter->first); string val = render_const_value(vtype, v_iter->second); - indent(out) << "Hashtbl.add " << hm << " " << key << " " << val << ";" << endl; + indent(out) << "Hashtbl.add " << hm << " " << key << " " << val << ";" << '\n'; } indent(out) << hm << ")"; indent_down(); @@ -443,14 +441,14 @@ string t_ocaml_generator::render_const_value(t_type* type, t_const_value* value) } else if (type->is_list()) { t_type* etype; etype = ((t_list*)type)->get_elem_type(); - out << "[" << endl; + out << "[" << '\n'; indent_up(); const vector& val = value->get_list(); vector::const_iterator v_iter; for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { out << indent(); out << render_const_value(etype, *v_iter); - out << ";" << endl; + out << ";" << '\n'; } indent_down(); indent(out) << "]"; @@ -459,15 +457,15 @@ string t_ocaml_generator::render_const_value(t_type* type, t_const_value* value) const vector& val = value->get_list(); vector::const_iterator v_iter; string hm = tmp("_hm"); - indent(out) << "(let " << hm << " = Hashtbl.create " << val.size() << " in" << endl; + indent(out) << "(let " << hm << " = Hashtbl.create " << val.size() << " in" << '\n'; indent_up(); for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { string val = render_const_value(etype, *v_iter); - indent(out) << "Hashtbl.add " << hm << " " << val << " true;" << endl; + indent(out) << "Hashtbl.add " << hm << " " << val << " true;" << '\n'; } - indent(out) << hm << ")" << endl; + indent(out) << hm << ")" << '\n'; indent_down(); - out << endl; + out << '\n'; } else { throw "CANNOT GENERATE CONSTANT FOR TYPE: " + type->get_name(); } @@ -503,15 +501,15 @@ void t_ocaml_generator::generate_ocaml_method_copy(ostream& out, const vector::const_iterator m_iter; /* Create a copy of the current object */ - indent(out) << "method copy =" << endl; + indent(out) << "method copy =" << '\n'; indent_up(); indent_up(); - indent(out) << "let _new = Oo.copy self in" << endl; + indent(out) << "let _new = Oo.copy self in" << '\n'; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) generate_ocaml_member_copy(out, *m_iter); indent_down(); - indent(out) << "_new" << endl; + indent(out) << "_new" << '\n'; indent_down(); } @@ -564,10 +562,10 @@ void t_ocaml_generator::generate_ocaml_member_copy(ostream& out, t_field* tmembe if (copy_of != grab_field) { indent(out); if (!struct_member_persistent(tmember)) { - out << "if _" << mname << " <> None then" << endl; + out << "if _" << mname << " <> None then" << '\n'; indent(out) << " "; } - out << "_new#set_" << mname << " " << copy_of << ";" << endl; + out << "_new#set_" << mname << " " << copy_of << ";" << '\n'; } } @@ -582,24 +580,24 @@ void t_ocaml_generator::generate_ocaml_struct_definition(ostream& out, const vector& members = tstruct->get_members(); vector::const_iterator m_iter; string tname = type_name(tstruct); - indent(out) << "class " << tname << " =" << endl; - indent(out) << "object (self)" << endl; + indent(out) << "class " << tname << " =" << '\n'; + indent(out) << "object (self)" << '\n'; indent_up(); if (members.size() > 0) { for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { generate_ocaml_struct_member(out, tname, (*m_iter)); - out << endl; + out << '\n'; } } generate_ocaml_method_copy(out, members); generate_ocaml_struct_writer(out, tstruct); indent_down(); - indent(out) << "end" << endl; + indent(out) << "end" << '\n'; if (is_exception) { - indent(out) << "exception " << capitalize(tname) << " of " << tname << endl; + indent(out) << "exception " << capitalize(tname) << " of " << tname << '\n'; } generate_ocaml_struct_reader(out, tstruct); @@ -621,37 +619,37 @@ void t_ocaml_generator::generate_ocaml_struct_member(ostream& out, t_const_value* val = tmember->get_value(); if (val) { if (struct_member_persistent(tmember)) - out << " = " << render_const_value(tmember->get_type(), tmember->get_value()) << endl; + out << " = " << render_const_value(tmember->get_type(), tmember->get_value()) << '\n'; else out << " option = Some " << render_const_value(tmember->get_type(), tmember->get_value()) - << endl; + << '\n'; } else { // assert(!struct_member_persistent(tmember)) - out << " option = None" << endl; + out << " option = None" << '\n'; } if (struct_member_persistent(tmember)) { - indent(out) << "method get_" << mname << " = Some _" << mname << endl; - indent(out) << "method grab_" << mname << " = _" << mname << endl; - indent(out) << "method set_" << mname << " " << x << " = _" << mname << " <- " << x << endl; + indent(out) << "method get_" << mname << " = Some _" << mname << '\n'; + indent(out) << "method grab_" << mname << " = _" << mname << '\n'; + indent(out) << "method set_" << mname << " " << x << " = _" << mname << " <- " << x << '\n'; } else { - indent(out) << "method get_" << mname << " = _" << mname << endl; + indent(out) << "method get_" << mname << " = _" << mname << '\n'; indent(out) << "method grab_" << mname << " = match _" << mname << " with None->raise (Field_empty \"" << tname << "." << mname << "\") | Some " - << x << " -> " << x << endl; + << x << " -> " << x << '\n'; indent(out) << "method set_" << mname << " " << x << " = _" << mname << " <- Some " << x - << endl; - indent(out) << "method unset_" << mname << " = _" << mname << " <- None" << endl; + << '\n'; + indent(out) << "method unset_" << mname << " = _" << mname << " <- None" << '\n'; } indent(out) << "method reset_" << mname << " = _" << mname << " <- "; if (val) { if (struct_member_persistent(tmember)) - out << render_const_value(tmember->get_type(), tmember->get_value()) << endl; + out << render_const_value(tmember->get_type(), tmember->get_value()) << '\n'; else - out << "Some " << render_const_value(tmember->get_type(), tmember->get_value()) << endl; + out << "Some " << render_const_value(tmember->get_type(), tmember->get_value()) << '\n'; } else { - out << "None" << endl; + out << "None" << '\n'; } } @@ -719,8 +717,8 @@ void t_ocaml_generator::generate_ocaml_struct_sig(ostream& out, const vector& members = tstruct->get_members(); vector::const_iterator m_iter; string tname = type_name(tstruct); - indent(out) << "class " << tname << " :" << endl; - indent(out) << "object ('a)" << endl; + indent(out) << "class " << tname << " :" << '\n'; + indent(out) << "object ('a)" << '\n'; indent_up(); @@ -729,24 +727,24 @@ void t_ocaml_generator::generate_ocaml_struct_sig(ostream& out, for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { string mname = decapitalize((*m_iter)->get_name()); string type = render_ocaml_type((*m_iter)->get_type()); - indent(out) << "method get_" << mname << " : " << type << " option" << endl; - indent(out) << "method grab_" << mname << " : " << type << endl; - indent(out) << "method set_" << mname << " : " << type << " -> unit" << endl; + indent(out) << "method get_" << mname << " : " << type << " option" << '\n'; + indent(out) << "method grab_" << mname << " : " << type << '\n'; + indent(out) << "method set_" << mname << " : " << type << " -> unit" << '\n'; if (!struct_member_persistent(*m_iter)) - indent(out) << "method unset_" << mname << " : unit" << endl; - indent(out) << "method reset_" << mname << " : unit" << endl; + indent(out) << "method unset_" << mname << " : unit" << '\n'; + indent(out) << "method reset_" << mname << " : unit" << '\n'; } } - indent(out) << "method copy : 'a" << endl; - indent(out) << "method write : Protocol.t -> unit" << endl; + indent(out) << "method copy : 'a" << '\n'; + indent(out) << "method write : Protocol.t -> unit" << '\n'; indent_down(); - indent(out) << "end" << endl; + indent(out) << "end" << '\n'; if (is_exception) { - indent(out) << "exception " << capitalize(tname) << " of " << tname << endl; + indent(out) << "exception " << capitalize(tname) << " of " << tname << '\n'; } - indent(out) << "val read_" << tname << " : Protocol.t -> " << tname << endl; + indent(out) << "val read_" << tname << " : Protocol.t -> " << tname << '\n'; } /** @@ -759,55 +757,55 @@ void t_ocaml_generator::generate_ocaml_struct_reader(ostream& out, t_struct* tst string str = tmp("_str"); string t = tmp("_t"); string id = tmp("_id"); - indent(out) << "let rec read_" << sname << " (iprot : Protocol.t) =" << endl; + indent(out) << "let rec read_" << sname << " (iprot : Protocol.t) =" << '\n'; indent_up(); - indent(out) << "let " << str << " = new " << sname << " in" << endl; + indent(out) << "let " << str << " = new " << sname << " in" << '\n'; indent_up(); - indent(out) << "ignore(iprot#readStructBegin);" << endl; + indent(out) << "ignore(iprot#readStructBegin);" << '\n'; // Loop over reading in fields - indent(out) << "(try while true do" << endl; + indent(out) << "(try while true do" << '\n'; indent_up(); indent_up(); // Read beginning field marker - indent(out) << "let (_," << t << "," << id << ") = iprot#readFieldBegin in" << endl; + indent(out) << "let (_," << t << "," << id << ") = iprot#readFieldBegin in" << '\n'; // Check for field STOP marker and break - indent(out) << "if " << t << " = Protocol.T_STOP then" << endl; + indent(out) << "if " << t << " = Protocol.T_STOP then" << '\n'; indent_up(); - indent(out) << "raise Break" << endl; + indent(out) << "raise Break" << '\n'; indent_down(); - indent(out) << "else ();" << endl; + indent(out) << "else ();" << '\n'; - indent(out) << "(match " << id << " with " << endl; + indent(out) << "(match " << id << " with " << '\n'; indent_up(); // Generate deserialization code for known cases for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { indent(out) << "| " << (*f_iter)->get_key() << " -> ("; - out << "if " << t << " = " << type_to_enum((*f_iter)->get_type()) << " then" << endl; + out << "if " << t << " = " << type_to_enum((*f_iter)->get_type()) << " then" << '\n'; indent_up(); indent_up(); generate_deserialize_field(out, *f_iter, str); indent_down(); - out << indent() << "else" << endl << indent() << " iprot#skip " << t << ")" << endl; + out << indent() << "else" << '\n' << indent() << " iprot#skip " << t << ")" << '\n'; indent_down(); } // In the default case we skip the field out << indent() << "| _ -> " - << "iprot#skip " << t << ");" << endl; + << "iprot#skip " << t << ");" << '\n'; indent_down(); // Read field end marker - indent(out) << "iprot#readFieldEnd;" << endl; + indent(out) << "iprot#readFieldEnd;" << '\n'; indent_down(); - indent(out) << "done; ()" << endl; + indent(out) << "done; ()" << '\n'; indent_down(); - indent(out) << "with Break -> ());" << endl; + indent(out) << "with Break -> ());" << '\n'; - indent(out) << "iprot#readStructEnd;" << endl; + indent(out) << "iprot#readStructEnd;" << '\n'; - indent(out) << str << endl << endl; + indent(out) << str << '\n' << '\n'; indent_down(); indent_down(); } @@ -819,9 +817,9 @@ void t_ocaml_generator::generate_ocaml_struct_writer(ostream& out, t_struct* tst string str = tmp("_str"); string f = tmp("_f"); - indent(out) << "method write (oprot : Protocol.t) =" << endl; + indent(out) << "method write (oprot : Protocol.t) =" << '\n'; indent_up(); - indent(out) << "oprot#writeStructBegin \"" << name << "\";" << endl; + indent(out) << "oprot#writeStructBegin \"" << name << "\";" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { t_field* tmember = (*f_iter); @@ -835,10 +833,10 @@ void t_ocaml_generator::generate_ocaml_struct_writer(ostream& out, t_struct* tst // Avoid redundant encoding of members having default values. indent(out) << "(match " << mname << " with " << render_const_value(tmember->get_type(), tmember->get_value()) << " -> () | " - << _v << " -> " << endl; + << _v << " -> " << '\n'; } else { _v = mname; - indent(out) << "(" << endl; + indent(out) << "(" << '\n'; } } else { @@ -853,12 +851,12 @@ void t_ocaml_generator::generate_ocaml_struct_writer(ostream& out, t_struct* tst out << " | Some " << render_const_value(tmember->get_type(), tmember->get_value()) << " -> ()"; } - out << " | Some _v -> " << endl; + out << " | Some _v -> " << '\n'; } else { - out << endl; + out << '\n'; indent(out) << "| None -> raise (Field_empty \"" << type_name(tstruct) << "." << mname - << "\")" << endl; - indent(out) << "| Some _v -> " << endl; + << "\")" << '\n'; + indent(out) << "| Some _v -> " << '\n'; } _v = "_v"; @@ -866,20 +864,20 @@ void t_ocaml_generator::generate_ocaml_struct_writer(ostream& out, t_struct* tst indent_up(); // Write field header indent(out) << "oprot#writeFieldBegin(\"" << tmember->get_name() << "\"," - << type_to_enum(tmember->get_type()) << "," << tmember->get_key() << ");" << endl; + << type_to_enum(tmember->get_type()) << "," << tmember->get_key() << ");" << '\n'; // Write field contents generate_serialize_field(out, tmember, _v); // Write field closer - indent(out) << "oprot#writeFieldEnd" << endl; + indent(out) << "oprot#writeFieldEnd" << '\n'; indent_down(); - indent(out) << ");" << endl; + indent(out) << ");" << '\n'; } // Write the struct map - out << indent() << "oprot#writeFieldStop;" << endl << indent() << "oprot#writeStructEnd" << endl; + out << indent() << "oprot#writeFieldStop;" << '\n' << indent() << "oprot#writeStructEnd" << '\n'; indent_down(); } @@ -895,19 +893,19 @@ void t_ocaml_generator::generate_service(t_service* tservice) { string f_service_i_name = get_out_dir() + capitalize(service_name_) + ".mli"; f_service_i_.open(f_service_i_name.c_str()); - f_service_ << ocaml_autogen_comment() << endl << ocaml_imports() << endl; - f_service_i_ << ocaml_autogen_comment() << endl << ocaml_imports() << endl; + f_service_ << ocaml_autogen_comment() << '\n' << ocaml_imports() << '\n'; + f_service_i_ << ocaml_autogen_comment() << '\n' << ocaml_imports() << '\n'; /* if (tservice->get_extends() != nullptr) { f_service_ << - "open " << capitalize(tservice->get_extends()->get_name()) << endl; + "open " << capitalize(tservice->get_extends()->get_name()) << '\n'; f_service_i_ << - "open " << capitalize(tservice->get_extends()->get_name()) << endl; + "open " << capitalize(tservice->get_extends()->get_name()) << '\n'; } */ - f_service_ << "open " << capitalize(program_name_) << "_types" << endl << endl; + f_service_ << "open " << capitalize(program_name_) << "_types" << '\n' << '\n'; - f_service_i_ << "open " << capitalize(program_name_) << "_types" << endl << endl; + f_service_i_ << "open " << capitalize(program_name_) << "_types" << '\n' << '\n'; // Generate the three main parts of the service generate_service_helpers(tservice); @@ -925,7 +923,7 @@ void t_ocaml_generator::generate_service_helpers(t_service* tservice) { vector functions = tservice->get_functions(); vector::iterator f_iter; - indent(f_service_) << "(* HELPER FUNCTIONS AND STRUCTURES *)" << endl << endl; + indent(f_service_) << "(* HELPER FUNCTIONS AND STRUCTURES *)" << '\n' << '\n'; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { t_struct* ts = (*f_iter)->get_arglist(); @@ -961,15 +959,15 @@ void t_ocaml_generator::generate_ocaml_function_helpers(t_function* tfunction) { * @param tservice The service to generate a header definition for */ void t_ocaml_generator::generate_service_interface(t_service* tservice) { - f_service_ << indent() << "class virtual iface =" << endl << "object (self)" << endl; - f_service_i_ << indent() << "class virtual iface :" << endl << "object" << endl; + f_service_ << indent() << "class virtual iface =" << '\n' << "object (self)" << '\n'; + f_service_i_ << indent() << "class virtual iface :" << '\n' << "object" << '\n'; indent_up(); if (tservice->get_extends() != nullptr) { string extends = type_name(tservice->get_extends()); - indent(f_service_) << "inherit " << extends << ".iface" << endl; - indent(f_service_i_) << "inherit " << extends << ".iface" << endl; + indent(f_service_) << "inherit " << extends << ".iface" << '\n'; + indent(f_service_i_) << "inherit " << extends << ".iface" << '\n'; } vector functions = tservice->get_functions(); @@ -977,13 +975,13 @@ void t_ocaml_generator::generate_service_interface(t_service* tservice) { for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { string ft = function_type(*f_iter, true, true); f_service_ << indent() << "method virtual " << decapitalize((*f_iter)->get_name()) << " : " - << ft << endl; + << ft << '\n'; f_service_i_ << indent() << "method virtual " << decapitalize((*f_iter)->get_name()) << " : " - << ft << endl; + << ft << '\n'; } indent_down(); - indent(f_service_) << "end" << endl << endl; - indent(f_service_i_) << "end" << endl << endl; + indent(f_service_) << "end" << '\n' << '\n'; + indent(f_service_i_) << "end" << '\n' << '\n'; } /** @@ -995,17 +993,17 @@ void t_ocaml_generator::generate_service_interface(t_service* tservice) { */ void t_ocaml_generator::generate_service_client(t_service* tservice) { string extends = ""; - indent(f_service_) << "class client (iprot : Protocol.t) (oprot : Protocol.t) =" << endl - << "object (self)" << endl; - indent(f_service_i_) << "class client : Protocol.t -> Protocol.t -> " << endl << "object" << endl; + indent(f_service_) << "class client (iprot : Protocol.t) (oprot : Protocol.t) =" << '\n' + << "object (self)" << '\n'; + indent(f_service_i_) << "class client : Protocol.t -> Protocol.t -> " << '\n' << "object" << '\n'; indent_up(); if (tservice->get_extends() != nullptr) { extends = type_name(tservice->get_extends()); - indent(f_service_) << "inherit " << extends << ".client iprot oprot as super" << endl; - indent(f_service_i_) << "inherit " << extends << ".client" << endl; + indent(f_service_) << "inherit " << extends << ".client iprot oprot as super" << '\n'; + indent(f_service_i_) << "inherit " << extends << ".client" << '\n'; } - indent(f_service_) << "val mutable seqid = 0" << endl; + indent(f_service_) << "val mutable seqid = 0" << '\n'; // Generate client method implementations vector functions = tservice->get_functions(); @@ -1017,24 +1015,24 @@ void t_ocaml_generator::generate_service_client(t_service* tservice) { string funname = (*f_iter)->get_name(); // Open function - indent(f_service_) << "method " << function_signature(*f_iter) << " = " << endl; + indent(f_service_) << "method " << function_signature(*f_iter) << " = " << '\n'; indent(f_service_i_) << "method " << decapitalize((*f_iter)->get_name()) << " : " - << function_type(*f_iter, true, false) << endl; + << function_type(*f_iter, true, false) << '\n'; indent_up(); indent(f_service_) << "self#send_" << funname; for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) { f_service_ << " " << decapitalize((*fld_iter)->get_name()); } - f_service_ << ";" << endl; + f_service_ << ";" << '\n'; if (!(*f_iter)->is_oneway()) { f_service_ << indent(); - f_service_ << "self#recv_" << funname << endl; + f_service_ << "self#recv_" << funname << '\n'; } indent_down(); - indent(f_service_) << "method private send_" << function_signature(*f_iter) << " = " << endl; + indent(f_service_) << "method private send_" << function_signature(*f_iter) << " = " << '\n'; indent_up(); std::string argsname = decapitalize((*f_iter)->get_name() + "_args"); @@ -1042,19 +1040,19 @@ void t_ocaml_generator::generate_service_client(t_service* tservice) { // Serialize the request header f_service_ << indent() << "oprot#writeMessageBegin (\"" << (*f_iter)->get_name() << "\", " << ((*f_iter)->is_oneway() ? "Protocol.ONEWAY" : "Protocol.CALL") << ", seqid);" - << endl; + << '\n'; - f_service_ << indent() << "let args = new " << argsname << " in" << endl; + f_service_ << indent() << "let args = new " << argsname << " in" << '\n'; indent_up(); for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) { f_service_ << indent() << "args#set_" << (*fld_iter)->get_name() << " " - << (*fld_iter)->get_name() << ";" << endl; + << (*fld_iter)->get_name() << ";" << '\n'; } // Write to the stream - f_service_ << indent() << "args#write oprot;" << endl << indent() << "oprot#writeMessageEnd;" - << endl << indent() << "oprot#getTransport#flush" << endl; + f_service_ << indent() << "args#write oprot;" << '\n' << indent() << "oprot#writeMessageEnd;" + << '\n' << indent() << "oprot#getTransport#flush" << '\n'; indent_down(); indent_down(); @@ -1068,20 +1066,20 @@ void t_ocaml_generator::generate_service_client(t_service* tservice) { &noargs); // Open function f_service_ << indent() << "method private " << function_signature(&recv_function) << " =" - << endl; + << '\n'; indent_up(); // TODO(mcslee): Validate message reply here, seq ids etc. - f_service_ << indent() << "let (fname, mtype, rseqid) = iprot#readMessageBegin in" << endl; + f_service_ << indent() << "let (fname, mtype, rseqid) = iprot#readMessageBegin in" << '\n'; indent_up(); - f_service_ << indent() << "(if mtype = Protocol.EXCEPTION then" << endl << indent() - << " let x = Application_Exn.read iprot in" << endl; + f_service_ << indent() << "(if mtype = Protocol.EXCEPTION then" << '\n' << indent() + << " let x = Application_Exn.read iprot in" << '\n'; indent_up(); f_service_ << indent() << " (iprot#readMessageEnd;" << indent() - << " raise (Application_Exn.E x))" << endl; + << " raise (Application_Exn.E x))" << '\n'; indent_down(); - f_service_ << indent() << "else ());" << endl; + f_service_ << indent() << "else ());" << '\n'; string res = "_"; t_struct* xs = (*f_iter)->get_xceptions(); @@ -1090,32 +1088,32 @@ void t_ocaml_generator::generate_service_client(t_service* tservice) { if (!(*f_iter)->get_returntype()->is_void() || xceptions.size() > 0) { res = "result"; } - f_service_ << indent() << "let " << res << " = read_" << resultname << " iprot in" << endl; + f_service_ << indent() << "let " << res << " = read_" << resultname << " iprot in" << '\n'; indent_up(); - f_service_ << indent() << "iprot#readMessageEnd;" << endl; + f_service_ << indent() << "iprot#readMessageEnd;" << '\n'; // Careful, only return _result if not a void function if (!(*f_iter)->get_returntype()->is_void()) { - f_service_ << indent() << "match result#get_success with Some v -> v | None -> (" << endl; + f_service_ << indent() << "match result#get_success with Some v -> v | None -> (" << '\n'; indent_up(); } vector::const_iterator x_iter; for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { f_service_ << indent() << "(match result#get_" << (*x_iter)->get_name() - << " with None -> () | Some _v ->" << endl; + << " with None -> () | Some _v ->" << '\n'; indent(f_service_) << " raise (" << capitalize(exception_ctor((*x_iter)->get_type())) - << " _v));" << endl; + << " _v));" << '\n'; } // Careful, only return _result if not a void function if ((*f_iter)->get_returntype()->is_void()) { - indent(f_service_) << "()" << endl; + indent(f_service_) << "()" << '\n'; } else { f_service_ << indent() << "raise (Application_Exn.E (Application_Exn.create Application_Exn.MISSING_RESULT \"" - << (*f_iter)->get_name() << " failed: unknown result\")))" << endl; + << (*f_iter)->get_name() << " failed: unknown result\")))" << '\n'; indent_down(); } @@ -1127,8 +1125,8 @@ void t_ocaml_generator::generate_service_client(t_service* tservice) { } indent_down(); - indent(f_service_) << "end" << endl << endl; - indent(f_service_i_) << "end" << endl << endl; + indent(f_service_) << "end" << '\n' << '\n'; + indent(f_service_i_) << "end" << '\n' << '\n'; } /** @@ -1142,50 +1140,50 @@ void t_ocaml_generator::generate_service_server(t_service* tservice) { vector::iterator f_iter; // Generate the header portion - indent(f_service_) << "class processor (handler : iface) =" << endl << indent() << "object (self)" - << endl; - indent(f_service_i_) << "class processor : iface ->" << endl << indent() << "object" << endl; + indent(f_service_) << "class processor (handler : iface) =" << '\n' << indent() << "object (self)" + << '\n'; + indent(f_service_i_) << "class processor : iface ->" << '\n' << indent() << "object" << '\n'; indent_up(); - f_service_ << indent() << "inherit Processor.t" << endl << endl; - f_service_i_ << indent() << "inherit Processor.t" << endl << endl; + f_service_ << indent() << "inherit Processor.t" << '\n' << '\n'; + f_service_i_ << indent() << "inherit Processor.t" << '\n' << '\n'; string extends = ""; if (tservice->get_extends() != nullptr) { extends = type_name(tservice->get_extends()); indent(f_service_) << "inherit " + extends + ".processor (handler :> " + extends + ".iface)" - << endl; - indent(f_service_i_) << "inherit " + extends + ".processor" << endl; + << '\n'; + indent(f_service_i_) << "inherit " + extends + ".processor" << '\n'; } if (extends.empty()) { - indent(f_service_) << "val processMap = Hashtbl.create " << functions.size() << endl; + indent(f_service_) << "val processMap = Hashtbl.create " << functions.size() << '\n'; } indent(f_service_i_) - << "val processMap : (string, int * Protocol.t * Protocol.t -> unit) Hashtbl.t" << endl; + << "val processMap : (string, int * Protocol.t * Protocol.t -> unit) Hashtbl.t" << '\n'; // Generate the server implementation - indent(f_service_) << "method process iprot oprot =" << endl; - indent(f_service_i_) << "method process : Protocol.t -> Protocol.t -> bool" << endl; + indent(f_service_) << "method process iprot oprot =" << '\n'; + indent(f_service_i_) << "method process : Protocol.t -> Protocol.t -> bool" << '\n'; indent_up(); - f_service_ << indent() << "let (name, typ, seqid) = iprot#readMessageBegin in" << endl; + f_service_ << indent() << "let (name, typ, seqid) = iprot#readMessageBegin in" << '\n'; indent_up(); // TODO(mcslee): validate message // HOT: dictionary function lookup - f_service_ << indent() << "if Hashtbl.mem processMap name then" << endl << indent() - << " (Hashtbl.find processMap name) (seqid, iprot, oprot)" << endl << indent() - << "else (" << endl << indent() << " iprot#skip(Protocol.T_STRUCT);" << endl - << indent() << " iprot#readMessageEnd;" << endl << indent() + f_service_ << indent() << "if Hashtbl.mem processMap name then" << '\n' << indent() + << " (Hashtbl.find processMap name) (seqid, iprot, oprot)" << '\n' << indent() + << "else (" << '\n' << indent() << " iprot#skip(Protocol.T_STRUCT);" << '\n' + << indent() << " iprot#readMessageEnd;" << '\n' << indent() << " let x = Application_Exn.create Application_Exn.UNKNOWN_METHOD (\"Unknown " - "function \"^name) in" << endl << indent() - << " oprot#writeMessageBegin(name, Protocol.EXCEPTION, seqid);" << endl << indent() - << " x#write oprot;" << endl << indent() << " oprot#writeMessageEnd;" << endl - << indent() << " oprot#getTransport#flush" << endl << indent() << ");" << endl; + "function \"^name) in" << '\n' << indent() + << " oprot#writeMessageBegin(name, Protocol.EXCEPTION, seqid);" << '\n' << indent() + << " x#write oprot;" << '\n' << indent() << " oprot#writeMessageEnd;" << '\n' + << indent() << " oprot#getTransport#flush" << '\n' << indent() << ");" << '\n'; // Read end of args field, the T_STOP, and the struct close - f_service_ << indent() << "true" << endl; + f_service_ << indent() << "true" << '\n'; indent_down(); indent_down(); // Generate the process subfunctions @@ -1193,17 +1191,17 @@ void t_ocaml_generator::generate_service_server(t_service* tservice) { generate_process_function(tservice, *f_iter); } - indent(f_service_) << "initializer" << endl; + indent(f_service_) << "initializer" << '\n'; indent_up(); for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { f_service_ << indent() << "Hashtbl.add processMap \"" << (*f_iter)->get_name() - << "\" self#process_" << (*f_iter)->get_name() << ";" << endl; + << "\" self#process_" << (*f_iter)->get_name() << ";" << '\n'; } indent_down(); indent_down(); - indent(f_service_) << "end" << endl << endl; - indent(f_service_i_) << "end" << endl << endl; + indent(f_service_) << "end" << '\n' << '\n'; + indent(f_service_i_) << "end" << '\n' << '\n'; } /** @@ -1215,7 +1213,7 @@ void t_ocaml_generator::generate_process_function(t_service* tservice, t_functio (void)tservice; // Open function indent(f_service_) << "method private process_" << tfunction->get_name() - << " (seqid, iprot, oprot) =" << endl; + << " (seqid, iprot, oprot) =" << '\n'; indent_up(); string argsname = decapitalize(tfunction->get_name()) + "_args"; @@ -1231,9 +1229,9 @@ void t_ocaml_generator::generate_process_function(t_service* tservice, t_functio args = "_"; } - f_service_ << indent() << "let " << args << " = read_" << argsname << " iprot in" << endl; + f_service_ << indent() << "let " << args << " = read_" << argsname << " iprot in" << '\n'; indent_up(); - f_service_ << indent() << "iprot#readMessageEnd;" << endl; + f_service_ << indent() << "iprot#readMessageEnd;" << '\n'; t_struct* xs = tfunction->get_xceptions(); const std::vector& xceptions = xs->get_members(); @@ -1241,13 +1239,13 @@ void t_ocaml_generator::generate_process_function(t_service* tservice, t_functio // Declare result for non oneway function if (!tfunction->is_oneway()) { - f_service_ << indent() << "let result = new " << resultname << " in" << endl; + f_service_ << indent() << "let result = new " << resultname << " in" << '\n'; indent_up(); } // Try block for a function with exceptions if (xceptions.size() > 0) { - f_service_ << indent() << "(try" << endl; + f_service_ << indent() << "(try" << '\n'; indent_up(); } @@ -1259,20 +1257,20 @@ void t_ocaml_generator::generate_process_function(t_service* tservice, t_functio for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { f_service_ << " args#get_" << (*f_iter)->get_name(); } - f_service_ << ");" << endl; + f_service_ << ");" << '\n'; if (xceptions.size() > 0) { indent_down(); - indent(f_service_) << "with" << endl; + indent(f_service_) << "with" << '\n'; indent_up(); for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { f_service_ << indent() << "| " << capitalize(exception_ctor((*x_iter)->get_type())) << " " - << (*x_iter)->get_name() << " -> " << endl; + << (*x_iter)->get_name() << " -> " << '\n'; indent_up(); indent_up(); if (!tfunction->is_oneway()) { f_service_ << indent() << "result#set_" << (*x_iter)->get_name() << " " - << (*x_iter)->get_name() << endl; + << (*x_iter)->get_name() << '\n'; } else { indent(f_service_) << "()"; } @@ -1280,21 +1278,21 @@ void t_ocaml_generator::generate_process_function(t_service* tservice, t_functio indent_down(); } indent_down(); - f_service_ << indent() << ");" << endl; + f_service_ << indent() << ");" << '\n'; } // Shortcut out here for oneway functions if (tfunction->is_oneway()) { - f_service_ << indent() << "()" << endl; + f_service_ << indent() << "()" << '\n'; indent_down(); indent_down(); return; } f_service_ << indent() << "oprot#writeMessageBegin (\"" << tfunction->get_name() - << "\", Protocol.REPLY, seqid);" << endl << indent() << "result#write oprot;" << endl - << indent() << "oprot#writeMessageEnd;" << endl << indent() - << "oprot#getTransport#flush" << endl; + << "\", Protocol.REPLY, seqid);" << '\n' << indent() << "result#write oprot;" << '\n' + << indent() << "oprot#writeMessageEnd;" << '\n' << indent() + << "oprot#getTransport#flush" << '\n'; // Close function indent_down(); @@ -1311,7 +1309,7 @@ void t_ocaml_generator::generate_deserialize_field(ostream& out, t_field* tfield string name = decapitalize(tfield->get_name()); indent(out) << prefix << "#set_" << name << " "; generate_deserialize_type(out, type); - out << endl; + out << '\n'; } /** @@ -1396,46 +1394,46 @@ void t_ocaml_generator::generate_deserialize_container(ostream& out, t_type* tty t_field fvtype(g_type_i8, vtype); t_field fetype(g_type_i8, etype); - out << endl; + out << '\n'; indent_up(); // Declare variables, read header if (ttype->is_map()) { indent(out) << "(let (" << ktype << "," << vtype << "," << size << ") = iprot#readMapBegin in" - << endl; - indent(out) << "let " << con << " = Hashtbl.create " << size << " in" << endl; + << '\n'; + indent(out) << "let " << con << " = Hashtbl.create " << size << " in" << '\n'; indent_up(); - indent(out) << "for i = 1 to " << size << " do" << endl; + indent(out) << "for i = 1 to " << size << " do" << '\n'; indent_up(); indent(out) << "let _k = "; generate_deserialize_type(out, ((t_map*)ttype)->get_key_type()); - out << " in" << endl; + out << " in" << '\n'; indent(out) << "let _v = "; generate_deserialize_type(out, ((t_map*)ttype)->get_val_type()); - out << " in" << endl; + out << " in" << '\n'; indent_up(); - indent(out) << "Hashtbl.add " << con << " _k _v" << endl; + indent(out) << "Hashtbl.add " << con << " _k _v" << '\n'; indent_down(); indent_down(); indent(out) << "done; iprot#readMapEnd; " << con << ")"; indent_down(); } else if (ttype->is_set()) { - indent(out) << "(let (" << etype << "," << size << ") = iprot#readSetBegin in" << endl; - indent(out) << "let " << con << " = Hashtbl.create " << size << " in" << endl; + indent(out) << "(let (" << etype << "," << size << ") = iprot#readSetBegin in" << '\n'; + indent(out) << "let " << con << " = Hashtbl.create " << size << " in" << '\n'; indent_up(); - indent(out) << "for i = 1 to " << size << " do" << endl; + indent(out) << "for i = 1 to " << size << " do" << '\n'; indent_up(); indent(out) << "Hashtbl.add " << con << " "; generate_deserialize_type(out, ((t_set*)ttype)->get_elem_type()); - out << " true" << endl; + out << " true" << '\n'; indent_down(); indent(out) << "done; iprot#readSetEnd; " << con << ")"; indent_down(); } else if (ttype->is_list()) { - indent(out) << "(let (" << etype << "," << size << ") = iprot#readListBegin in" << endl; + indent(out) << "(let (" << etype << "," << size << ") = iprot#readListBegin in" << '\n'; indent_up(); indent(out) << "let " << con << " = (Array.to_list (Array.init " << size << " (fun _ -> "; generate_deserialize_type(out, ((t_list*)ttype)->get_elem_type()); - out << "))) in" << endl; + out << "))) in" << '\n'; indent_up(); indent(out) << "iprot#readListEnd; " << con << ")"; indent_down(); @@ -1510,7 +1508,7 @@ void t_ocaml_generator::generate_serialize_field(ostream& out, t_field* tfield, tfield->get_name().c_str(), type->get_name().c_str()); } - out << ";" << endl; + out << ";" << '\n'; } /** @@ -1528,38 +1526,38 @@ void t_ocaml_generator::generate_serialize_container(ostream& out, t_type* ttype if (ttype->is_map()) { indent(out) << "oprot#writeMapBegin(" << type_to_enum(((t_map*)ttype)->get_key_type()) << ","; out << type_to_enum(((t_map*)ttype)->get_val_type()) << ","; - out << "Hashtbl.length " << prefix << ");" << endl; + out << "Hashtbl.length " << prefix << ");" << '\n'; } else if (ttype->is_set()) { indent(out) << "oprot#writeSetBegin(" << type_to_enum(((t_set*)ttype)->get_elem_type()) << ","; - out << "Hashtbl.length " << prefix << ");" << endl; + out << "Hashtbl.length " << prefix << ");" << '\n'; } else if (ttype->is_list()) { indent(out) << "oprot#writeListBegin(" << type_to_enum(((t_list*)ttype)->get_elem_type()) << ","; - out << "List.length " << prefix << ");" << endl; + out << "List.length " << prefix << ");" << '\n'; } if (ttype->is_map()) { string kiter = tmp("_kiter"); string viter = tmp("_viter"); - indent(out) << "Hashtbl.iter (fun " << kiter << " -> fun " << viter << " -> " << endl; + indent(out) << "Hashtbl.iter (fun " << kiter << " -> fun " << viter << " -> " << '\n'; indent_up(); generate_serialize_map_element(out, (t_map*)ttype, kiter, viter); indent_down(); - indent(out) << ") " << prefix << ";" << endl; + indent(out) << ") " << prefix << ";" << '\n'; } else if (ttype->is_set()) { string iter = tmp("_iter"); indent(out) << "Hashtbl.iter (fun " << iter << " -> fun _ -> "; indent_up(); generate_serialize_set_element(out, (t_set*)ttype, iter); indent_down(); - indent(out) << ") " << prefix << ";" << endl; + indent(out) << ") " << prefix << ";" << '\n'; } else if (ttype->is_list()) { string iter = tmp("_iter"); indent(out) << "List.iter (fun " << iter << " -> "; indent_up(); generate_serialize_list_element(out, (t_list*)ttype, iter); indent_down(); - indent(out) << ") " << prefix << ";" << endl; + indent(out) << ") " << prefix << ";" << '\n'; } if (ttype->is_map()) { diff --git a/compiler/cpp/src/thrift/generate/t_oop_generator.h b/compiler/cpp/src/thrift/generate/t_oop_generator.h index 88419620333..07b621639f7 100644 --- a/compiler/cpp/src/thrift/generate/t_oop_generator.h +++ b/compiler/cpp/src/thrift/generate/t_oop_generator.h @@ -42,13 +42,13 @@ class t_oop_generator : public t_generator { */ void scope_up(std::ostream& out) { - indent(out) << "{" << std::endl; + indent(out) << "{" << '\n'; indent_up(); } void scope_down(std::ostream& out) { indent_down(); - indent(out) << "}" << std::endl; + indent(out) << "}" << '\n'; } std::string upcase_string(std::string original) { diff --git a/compiler/cpp/src/thrift/generate/t_perl_generator.cc b/compiler/cpp/src/thrift/generate/t_perl_generator.cc index d133b2455b5..8e533ca2903 100644 --- a/compiler/cpp/src/thrift/generate/t_perl_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_perl_generator.cc @@ -37,8 +37,6 @@ using std::string; using std::stringstream; using std::vector; -static const string endl = "\n"; // avoid ostream << std::endl flushes - /** * PERL code generator. * @@ -246,8 +244,8 @@ void t_perl_generator::init_generator() { f_types_ << autogen_comment() << perl_includes(); // Print header - f_consts_ << autogen_comment() << "package " << perl_namespace(program_) << "Constants;" << endl - << perl_includes() << endl; + f_consts_ << autogen_comment() << "package " << perl_namespace(program_) << "Constants;" << '\n' + << perl_includes() << '\n'; } /** @@ -271,10 +269,10 @@ string t_perl_generator::perl_includes() { */ void t_perl_generator::close_generator() { // Close types file - f_types_ << "1;" << endl; + f_types_ << "1;" << '\n'; f_types_.close(); - f_consts_ << "1;" << endl; + f_consts_ << "1;" << '\n'; f_consts_.close(); } @@ -294,13 +292,13 @@ void t_perl_generator::generate_typedef(t_typedef* ttypedef) { * @param tenum The enumeration */ void t_perl_generator::generate_enum(t_enum* tenum) { - f_types_ << "package " << perl_namespace(program_) << tenum->get_name() << ";" << endl; + f_types_ << "package " << perl_namespace(program_) << tenum->get_name() << ";" << '\n'; vector constants = tenum->get_constants(); vector::iterator c_iter; for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) { int value = (*c_iter)->get_value(); - f_types_ << "use constant " << (*c_iter)->get_name() << " => " << value << ";" << endl; + f_types_ << "use constant " << (*c_iter)->get_name() << " => " << value << ";" << '\n'; } } @@ -314,7 +312,7 @@ void t_perl_generator::generate_const(t_const* tconst) { f_consts_ << "use constant " << name << " => "; f_consts_ << render_const_value(type, value); - f_consts_ << ";" << endl << endl; + f_consts_ << ";" << '\n' << '\n'; } /** @@ -355,7 +353,7 @@ string t_perl_generator::render_const_value(t_type* type, t_const_value* value) } else if (type->is_enum()) { out << value->get_integer(); } else if (type->is_struct() || type->is_xception()) { - out << perl_namespace(type->get_program()) << type->get_name() << "->new({" << endl; + out << perl_namespace(type->get_program()) << type->get_name() << "->new({" << '\n'; indent_up(); const vector& fields = ((t_struct*)type)->get_members(); @@ -376,14 +374,14 @@ string t_perl_generator::render_const_value(t_type* type, t_const_value* value) out << " => "; out << render_const_value(field_type, v_iter->second); out << ","; - out << endl; + out << '\n'; } indent_down(); indent(out) << "})"; } else if (type->is_map()) { t_type* ktype = ((t_map*)type)->get_key_type(); t_type* vtype = ((t_map*)type)->get_val_type(); - out << "{" << endl; + out << "{" << '\n'; indent_up(); const map& val = value->get_map(); @@ -392,7 +390,7 @@ string t_perl_generator::render_const_value(t_type* type, t_const_value* value) indent(out) << render_const_value(ktype, v_iter->first); out << " => "; out << render_const_value(vtype, v_iter->second); - out << "," << endl; + out << "," << '\n'; } indent_down(); indent(out) << "}"; @@ -403,7 +401,7 @@ string t_perl_generator::render_const_value(t_type* type, t_const_value* value) } else { etype = ((t_set*)type)->get_elem_type(); } - out << "[" << endl; + out << "[" << '\n'; indent_up(); const vector& val = value->get_list(); @@ -414,7 +412,7 @@ string t_perl_generator::render_const_value(t_type* type, t_const_value* value) if (type->is_set()) { out << " => 1"; } - out << "," << endl; + out << "," << '\n'; } indent_down(); indent(out) << "]"; @@ -480,12 +478,12 @@ void t_perl_generator::generate_perl_struct_definition(ostream& out, out << ") );\n"; } - out << endl; + out << '\n'; // new() indent_up(); - out << "sub new {" << endl << indent() << "my $classname = shift;" << endl << indent() - << "my $self = {};" << endl << indent() << "my $vals = shift || {};" << endl; + out << "sub new {" << '\n' << indent() << "my $classname = shift;" << '\n' << indent() + << "my $self = {};" << '\n' << indent() << "my $vals = shift || {};" << '\n'; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { string dval = "undef"; @@ -493,7 +491,7 @@ void t_perl_generator::generate_perl_struct_definition(ostream& out, if ((*m_iter)->get_value() != nullptr && !(t->is_struct() || t->is_xception())) { dval = render_const_value((*m_iter)->get_type(), (*m_iter)->get_value()); } - out << indent() << "$self->{" << (*m_iter)->get_name() << "} = " << dval << ";" << endl; + out << indent() << "$self->{" << (*m_iter)->get_name() << "} = " << dval << ";" << '\n'; } // Generate constructor from array @@ -503,27 +501,27 @@ void t_perl_generator::generate_perl_struct_definition(ostream& out, t_type* t = get_true_type((*m_iter)->get_type()); if ((*m_iter)->get_value() != nullptr && (t->is_struct() || t->is_xception())) { indent(out) << "$self->{" << (*m_iter)->get_name() - << "} = " << render_const_value(t, (*m_iter)->get_value()) << ";" << endl; + << "} = " << render_const_value(t, (*m_iter)->get_value()) << ";" << '\n'; } } - out << indent() << "if (UNIVERSAL::isa($vals,'HASH')) {" << endl; + out << indent() << "if (UNIVERSAL::isa($vals,'HASH')) {" << '\n'; indent_up(); for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { - out << indent() << "if (defined $vals->{" << (*m_iter)->get_name() << "}) {" << endl + out << indent() << "if (defined $vals->{" << (*m_iter)->get_name() << "}) {" << '\n' << indent() << " $self->{" << (*m_iter)->get_name() << "} = $vals->{" - << (*m_iter)->get_name() << "};" << endl << indent() << "}" << endl; + << (*m_iter)->get_name() << "};" << '\n' << indent() << "}" << '\n'; } indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } - out << indent() << "return bless ($self, $classname);" << endl; + out << indent() << "return bless ($self, $classname);" << '\n'; indent_down(); out << "}\n\n"; - out << "sub getName {" << endl << indent() << " return '" << tstruct->get_name() << "';" << endl - << indent() << "}" << endl << endl; + out << "sub getName {" << '\n' << indent() << " return '" << tstruct->get_name() << "';" << '\n' + << indent() << "}" << '\n' << '\n'; generate_perl_struct_reader(out, tstruct); generate_perl_struct_writer(out, tstruct); @@ -536,32 +534,32 @@ void t_perl_generator::generate_perl_struct_reader(ostream& out, t_struct* tstru const vector& fields = tstruct->get_members(); vector::const_iterator f_iter; - out << "sub read {" << endl; + out << "sub read {" << '\n'; indent_up(); - out << indent() << "my ($self, $input) = @_;" << endl << indent() << "my $xfer = 0;" << endl - << indent() << "my $fname;" << endl << indent() << "my $ftype = 0;" << endl << indent() - << "my $fid = 0;" << endl; + out << indent() << "my ($self, $input) = @_;" << '\n' << indent() << "my $xfer = 0;" << '\n' + << indent() << "my $fname;" << '\n' << indent() << "my $ftype = 0;" << '\n' << indent() + << "my $fid = 0;" << '\n'; - indent(out) << "$xfer += $input->readStructBegin(\\$fname);" << endl; + indent(out) << "$xfer += $input->readStructBegin(\\$fname);" << '\n'; // Loop over reading in fields - indent(out) << "while (1)" << endl; + indent(out) << "while (1)" << '\n'; scope_up(out); - indent(out) << "$xfer += $input->readFieldBegin(\\$fname, \\$ftype, \\$fid);" << endl; + indent(out) << "$xfer += $input->readFieldBegin(\\$fname, \\$ftype, \\$fid);" << '\n'; // Check for field STOP marker and break - indent(out) << "if ($ftype == Thrift::TType::STOP) {" << endl; + indent(out) << "if ($ftype == Thrift::TType::STOP) {" << '\n'; indent_up(); - indent(out) << "last;" << endl; + indent(out) << "last;" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; // Switch statement on the field we are reading - indent(out) << "SWITCH: for($fid)" << endl; + indent(out) << "SWITCH: for($fid)" << '\n'; scope_up(out); @@ -569,34 +567,34 @@ void t_perl_generator::generate_perl_struct_reader(ostream& out, t_struct* tstru for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { indent(out) << "/^" << (*f_iter)->get_key() << "$/ && do{"; - indent(out) << "if ($ftype == " << type_to_enum((*f_iter)->get_type()) << ") {" << endl; + indent(out) << "if ($ftype == " << type_to_enum((*f_iter)->get_type()) << ") {" << '\n'; indent_up(); generate_deserialize_field(out, *f_iter, "self->"); indent_down(); - indent(out) << "} else {" << endl; + indent(out) << "} else {" << '\n'; - indent(out) << " $xfer += $input->skip($ftype);" << endl; + indent(out) << " $xfer += $input->skip($ftype);" << '\n'; - out << indent() << "}" << endl << indent() << "last; };" << endl; + out << indent() << "}" << '\n' << indent() << "last; };" << '\n'; } // In the default case we skip the field - indent(out) << " $xfer += $input->skip($ftype);" << endl; + indent(out) << " $xfer += $input->skip($ftype);" << '\n'; scope_down(out); - indent(out) << "$xfer += $input->readFieldEnd();" << endl; + indent(out) << "$xfer += $input->readFieldEnd();" << '\n'; scope_down(out); - indent(out) << "$xfer += $input->readStructEnd();" << endl; + indent(out) << "$xfer += $input->readStructEnd();" << '\n'; - indent(out) << "return $xfer;" << endl; + indent(out) << "return $xfer;" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } /** @@ -607,38 +605,38 @@ void t_perl_generator::generate_perl_struct_writer(ostream& out, t_struct* tstru const vector& fields = tstruct->get_sorted_members(); vector::const_iterator f_iter; - out << "sub write {" << endl; + out << "sub write {" << '\n'; indent_up(); - indent(out) << "my ($self, $output) = @_;" << endl; - indent(out) << "my $xfer = 0;" << endl; + indent(out) << "my ($self, $output) = @_;" << '\n'; + indent(out) << "my $xfer = 0;" << '\n'; - indent(out) << "$xfer += $output->writeStructBegin('" << name << "');" << endl; + indent(out) << "$xfer += $output->writeStructBegin('" << name << "');" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { - out << indent() << "if (defined $self->{" << (*f_iter)->get_name() << "}) {" << endl; + out << indent() << "if (defined $self->{" << (*f_iter)->get_name() << "}) {" << '\n'; indent_up(); indent(out) << "$xfer += $output->writeFieldBegin(" << "'" << (*f_iter)->get_name() << "', " << type_to_enum((*f_iter)->get_type()) - << ", " << (*f_iter)->get_key() << ");" << endl; + << ", " << (*f_iter)->get_key() << ");" << '\n'; // Write field contents generate_serialize_field(out, *f_iter, "self->"); - indent(out) << "$xfer += $output->writeFieldEnd();" << endl; + indent(out) << "$xfer += $output->writeFieldEnd();" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } - out << indent() << "$xfer += $output->writeFieldStop();" << endl << indent() - << "$xfer += $output->writeStructEnd();" << endl; + out << indent() << "$xfer += $output->writeFieldStop();" << '\n' << indent() + << "$xfer += $output->writeStructEnd();" << '\n'; - out << indent() << "return $xfer;" << endl; + out << indent() << "return $xfer;" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; } /** @@ -655,13 +653,13 @@ void t_perl_generator::generate_use_includes(std::ostream& os, bool& done, t_typ std::vector& currInc = current->get_includes(); std::vector::size_type numInc = currInc.size(); if (selfish) { - os << "use " << perl_namespace(current) << "Types;" << endl; + os << "use " << perl_namespace(current) << "Types;" << '\n'; } for (std::vector::size_type i = 0; i < numInc; ++i) { t_program* incProgram = currInc.at(i); - os << "use " << perl_namespace(incProgram) << "Types;" << endl; + os << "use " << perl_namespace(incProgram) << "Types;" << '\n'; } - os << endl; + os << '\n'; done = true; } } @@ -683,10 +681,10 @@ void t_perl_generator::generate_service(t_service* tservice) { t_service* extends_s = tservice->get_extends(); if (extends_s != nullptr) { f_service_ << "use " << perl_namespace(extends_s->get_program()) << extends_s->get_name() << ";" - << endl; + << '\n'; } - f_service_ << endl; + f_service_ << '\n'; // Generate the three main parts of the service (well, two for now in PERL) generate_service_helpers(tservice); @@ -696,7 +694,7 @@ void t_perl_generator::generate_service(t_service* tservice) { generate_service_processor(tservice); // Close service file - f_service_ << "1;" << endl; + f_service_ << "1;" << '\n'; f_service_.close(); } @@ -721,59 +719,59 @@ void t_perl_generator::generate_service_processor(t_service* tservice) { indent_up(); // Generate the header portion - f_service_ << "package " << perl_namespace(program_) << service_name_ << "Processor;" << endl - << endl << "use strict;" << endl << extends_processor << endl << endl; + f_service_ << "package " << perl_namespace(program_) << service_name_ << "Processor;" << '\n' + << '\n' << "use strict;" << '\n' << extends_processor << '\n' << '\n'; if (extends.empty()) { - f_service_ << "sub new {" << endl; + f_service_ << "sub new {" << '\n'; indent_up(); - f_service_ << indent() << "my ($classname, $handler) = @_;" << endl << indent() - << "my $self = {};" << endl; + f_service_ << indent() << "my ($classname, $handler) = @_;" << '\n' << indent() + << "my $self = {};" << '\n'; - f_service_ << indent() << "$self->{handler} = $handler;" << endl; + f_service_ << indent() << "$self->{handler} = $handler;" << '\n'; - f_service_ << indent() << "return bless ($self, $classname);" << endl; + f_service_ << indent() << "return bless ($self, $classname);" << '\n'; indent_down(); - f_service_ << "}" << endl << endl; + f_service_ << "}" << '\n' << '\n'; } // Generate the server implementation - f_service_ << "sub process {" << endl; + f_service_ << "sub process {" << '\n'; indent_up(); - f_service_ << indent() << "my ($self, $input, $output) = @_;" << endl; + f_service_ << indent() << "my ($self, $input, $output) = @_;" << '\n'; - f_service_ << indent() << "my $rseqid = 0;" << endl << indent() << "my $fname = undef;" << endl - << indent() << "my $mtype = 0;" << endl << endl; + f_service_ << indent() << "my $rseqid = 0;" << '\n' << indent() << "my $fname = undef;" << '\n' + << indent() << "my $mtype = 0;" << '\n' << '\n'; - f_service_ << indent() << "$input->readMessageBegin(\\$fname, \\$mtype, \\$rseqid);" << endl; + f_service_ << indent() << "$input->readMessageBegin(\\$fname, \\$mtype, \\$rseqid);" << '\n'; // HOT: check for method implementation - f_service_ << indent() << "my $methodname = 'process_'.$fname;" << endl << indent() - << "if (!$self->can($methodname)) {" << endl; + f_service_ << indent() << "my $methodname = 'process_'.$fname;" << '\n' << indent() + << "if (!$self->can($methodname)) {" << '\n'; indent_up(); - f_service_ << indent() << "$input->skip(Thrift::TType::STRUCT);" << endl << indent() - << "$input->readMessageEnd();" << endl << indent() + f_service_ << indent() << "$input->skip(Thrift::TType::STRUCT);" << '\n' << indent() + << "$input->readMessageEnd();" << '\n' << indent() << "my $x = Thrift::TApplicationException->new('Function '.$fname.' not implemented.', " - "Thrift::TApplicationException::UNKNOWN_METHOD);" << endl << indent() - << "$output->writeMessageBegin($fname, Thrift::TMessageType::EXCEPTION, $rseqid);" << endl - << indent() << "$x->write($output);" << endl << indent() - << "$output->writeMessageEnd();" << endl << indent() - << "$output->getTransport()->flush();" << endl << indent() << "return;" << endl; + "Thrift::TApplicationException::UNKNOWN_METHOD);" << '\n' << indent() + << "$output->writeMessageBegin($fname, Thrift::TMessageType::EXCEPTION, $rseqid);" << '\n' + << indent() << "$x->write($output);" << '\n' << indent() + << "$output->writeMessageEnd();" << '\n' << indent() + << "$output->getTransport()->flush();" << '\n' << indent() << "return;" << '\n'; indent_down(); - f_service_ << indent() << "}" << endl << indent() - << "$self->$methodname($rseqid, $input, $output);" << endl << indent() << "return 1;" - << endl; + f_service_ << indent() << "}" << '\n' << indent() + << "$self->$methodname($rseqid, $input, $output);" << '\n' << indent() << "return 1;" + << '\n'; indent_down(); - f_service_ << "}" << endl << endl; + f_service_ << "}" << '\n' << '\n'; // Generate the process subfunctions for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { @@ -788,21 +786,21 @@ void t_perl_generator::generate_service_processor(t_service* tservice) { */ void t_perl_generator::generate_process_function(t_service* tservice, t_function* tfunction) { // Open function - f_service_ << "sub process_" << tfunction->get_name() << " {" << endl; + f_service_ << "sub process_" << tfunction->get_name() << " {" << '\n'; indent_up(); - f_service_ << indent() << "my ($self, $seqid, $input, $output) = @_;" << endl; + f_service_ << indent() << "my ($self, $seqid, $input, $output) = @_;" << '\n'; string argsname = perl_namespace(tservice->get_program()) + service_name_ + "_" + tfunction->get_name() + "_args"; string resultname = perl_namespace(tservice->get_program()) + service_name_ + "_" + tfunction->get_name() + "_result"; - f_service_ << indent() << "my $args = " << argsname << "->new();" << endl << indent() - << "$args->read($input);" << endl; + f_service_ << indent() << "my $args = " << argsname << "->new();" << '\n' << indent() + << "$args->read($input);" << '\n'; - f_service_ << indent() << "$input->readMessageEnd();" << endl; + f_service_ << indent() << "$input->readMessageEnd();" << '\n'; t_struct* xs = tfunction->get_xceptions(); const std::vector& xceptions = xs->get_members(); @@ -810,12 +808,12 @@ void t_perl_generator::generate_process_function(t_service* tservice, t_function // Declare result for non oneway function if (!tfunction->is_oneway()) { - f_service_ << indent() << "my $result = " << resultname << "->new();" << endl; + f_service_ << indent() << "my $result = " << resultname << "->new();" << '\n'; } // Try block for a function with exceptions if (xceptions.size() > 0) { - f_service_ << indent() << "eval {" << endl; + f_service_ << indent() << "eval {" << '\n'; indent_up(); } @@ -838,55 +836,55 @@ void t_perl_generator::generate_process_function(t_service* tservice, t_function } f_service_ << "$args->" << (*f_iter)->get_name(); } - f_service_ << ");" << endl; + f_service_ << ");" << '\n'; if (!tfunction->is_oneway() && xceptions.size() > 0) { indent_down(); for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { f_service_ << indent() << "}; if( UNIVERSAL::isa($@,'" << perl_namespace((*x_iter)->get_type()->get_program()) - << (*x_iter)->get_type()->get_name() << "') ){ " << endl; + << (*x_iter)->get_type()->get_name() << "') ){ " << '\n'; indent_up(); - f_service_ << indent() << "$result->{" << (*x_iter)->get_name() << "} = $@;" << endl; - f_service_ << indent() << "$@ = undef;" << endl; + f_service_ << indent() << "$result->{" << (*x_iter)->get_name() << "} = $@;" << '\n'; + f_service_ << indent() << "$@ = undef;" << '\n'; indent_down(); f_service_ << indent(); } - f_service_ << "}" << endl; + f_service_ << "}" << '\n'; // catch-all for unexpected exceptions (THRIFT-3191) - f_service_ << indent() << "if ($@) {" << endl; + f_service_ << indent() << "if ($@) {" << '\n'; indent_up(); - f_service_ << indent() << "$@ =~ s/^\\s+|\\s+$//g;" << endl - << indent() << "my $err = Thrift::TApplicationException->new(\"Unexpected Exception: \" . $@, Thrift::TApplicationException::INTERNAL_ERROR);" << endl - << indent() << "$output->writeMessageBegin('" << tfunction->get_name() << "', Thrift::TMessageType::EXCEPTION, $seqid);" << endl - << indent() << "$err->write($output);" << endl - << indent() << "$output->writeMessageEnd();" << endl - << indent() << "$output->getTransport()->flush();" << endl - << indent() << "$@ = undef;" << endl - << indent() << "return;" << endl; + f_service_ << indent() << "$@ =~ s/^\\s+|\\s+$//g;" << '\n' + << indent() << "my $err = Thrift::TApplicationException->new(\"Unexpected Exception: \" . $@, Thrift::TApplicationException::INTERNAL_ERROR);" << '\n' + << indent() << "$output->writeMessageBegin('" << tfunction->get_name() << "', Thrift::TMessageType::EXCEPTION, $seqid);" << '\n' + << indent() << "$err->write($output);" << '\n' + << indent() << "$output->writeMessageEnd();" << '\n' + << indent() << "$output->getTransport()->flush();" << '\n' + << indent() << "$@ = undef;" << '\n' + << indent() << "return;" << '\n'; indent_down(); - f_service_ << indent() << "}" << endl; + f_service_ << indent() << "}" << '\n'; } // Shortcut out here for oneway functions if (tfunction->is_oneway()) { - f_service_ << indent() << "return;" << endl; + f_service_ << indent() << "return;" << '\n'; indent_down(); - f_service_ << "}" << endl; + f_service_ << "}" << '\n'; return; } // Serialize the reply - f_service_ << indent() << "$output->writeMessageBegin('" << tfunction->get_name() << "', Thrift::TMessageType::REPLY, $seqid);" << endl - << indent() << "$result->write($output);" << endl - << indent() << "$output->writeMessageEnd();" << endl - << indent() << "$output->getTransport()->flush();" << endl; + f_service_ << indent() << "$output->writeMessageBegin('" << tfunction->get_name() << "', Thrift::TMessageType::REPLY, $seqid);" << '\n' + << indent() << "$result->write($output);" << '\n' + << indent() << "$output->writeMessageEnd();" << '\n' + << indent() << "$output->getTransport()->flush();" << '\n'; // Close function indent_down(); - f_service_ << "}" << endl << endl; + f_service_ << "}" << '\n' << '\n'; } /** @@ -898,7 +896,7 @@ void t_perl_generator::generate_service_helpers(t_service* tservice) { vector functions = tservice->get_functions(); vector::iterator f_iter; - f_service_ << "# HELPER FUNCTIONS AND STRUCTURES" << endl << endl; + f_service_ << "# HELPER FUNCTIONS AND STRUCTURES" << '\n' << '\n'; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { t_struct* ts = (*f_iter)->get_arglist(); @@ -945,15 +943,15 @@ void t_perl_generator::generate_service_interface(t_service* tservice) { + "If);"; } - f_service_ << "package " << perl_namespace(program_) << service_name_ << "If;" << endl << endl - << "use strict;" << endl << extends_if << endl << endl; + f_service_ << "package " << perl_namespace(program_) << service_name_ << "If;" << '\n' << '\n' + << "use strict;" << '\n' << extends_if << '\n' << '\n'; indent_up(); vector functions = tservice->get_functions(); vector::iterator f_iter; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { - f_service_ << "sub " << function_signature(*f_iter) << endl << " die 'implement interface';\n}" - << endl << endl; + f_service_ << "sub " << function_signature(*f_iter) << '\n' << " die 'implement interface';\n}" + << '\n' << '\n'; } indent_down(); } @@ -970,31 +968,31 @@ void t_perl_generator::generate_service_rest(t_service* tservice) { extends_if = "use base qw(" + perl_namespace(extends_s->get_program()) + extends_s->get_name() + "Rest);"; } - f_service_ << "package " << perl_namespace(program_) << service_name_ << "Rest;" << endl << endl - << "use strict;" << endl << extends_if << endl << endl; + f_service_ << "package " << perl_namespace(program_) << service_name_ << "Rest;" << '\n' << '\n' + << "use strict;" << '\n' << extends_if << '\n' << '\n'; if (extends.empty()) { - f_service_ << "sub new {" << endl; + f_service_ << "sub new {" << '\n'; indent_up(); - f_service_ << indent() << "my ($classname, $impl) = @_;" << endl << indent() - << "my $self ={ impl => $impl };" << endl << endl << indent() - << "return bless($self,$classname);" << endl; + f_service_ << indent() << "my ($classname, $impl) = @_;" << '\n' << indent() + << "my $self ={ impl => $impl };" << '\n' << '\n' << indent() + << "return bless($self,$classname);" << '\n'; indent_down(); - f_service_ << "}" << endl << endl; + f_service_ << "}" << '\n' << '\n'; } vector functions = tservice->get_functions(); vector::iterator f_iter; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { - f_service_ << "sub " << (*f_iter)->get_name() << "{" << endl; + f_service_ << "sub " << (*f_iter)->get_name() << "{" << '\n'; indent_up(); - f_service_ << indent() << "my ($self, $request) = @_;" << endl << endl; + f_service_ << indent() << "my ($self, $request) = @_;" << '\n' << '\n'; const vector& args = (*f_iter)->get_arglist()->get_members(); vector::const_iterator a_iter; @@ -1002,19 +1000,19 @@ void t_perl_generator::generate_service_rest(t_service* tservice) { //t_type* atype = get_true_type((*a_iter)->get_type()); string req = "$request->{'" + (*a_iter)->get_name() + "'}"; f_service_ << indent() << "my $" << (*a_iter)->get_name() << " = (" << req << ") ? " << req - << " : undef;" << endl; + << " : undef;" << '\n'; /* slist no longer supported if (atype->is_string() && ((t_base_type*)atype)->is_string_list()) { f_service_ << indent() << "my @" << (*a_iter)->get_name() << " = split(/,/, $" - << (*a_iter)->get_name() << ");" << endl << indent() << "$" - << (*a_iter)->get_name() << " = \\@" << (*a_iter)->get_name() << endl; + << (*a_iter)->get_name() << ");" << '\n' << indent() << "$" + << (*a_iter)->get_name() << " = \\@" << (*a_iter)->get_name() << '\n'; } */ } f_service_ << indent() << "return $self->{impl}->" << (*f_iter)->get_name() << "(" - << argument_list((*f_iter)->get_arglist()) << ");" << endl; + << argument_list((*f_iter)->get_arglist()) << ");" << '\n'; indent_down(); - indent(f_service_) << "}" << endl << endl; + indent(f_service_) << "}" << '\n' << '\n'; } } @@ -1032,31 +1030,31 @@ void t_perl_generator::generate_service_client(t_service* tservice) { extends_client = "use base qw(" + extends + "Client);"; } - f_service_ << "package " << perl_namespace(program_) << service_name_ << "Client;" << endl << endl - << extends_client << endl << "use base qw(" << perl_namespace(program_) - << service_name_ << "If);" << endl; + f_service_ << "package " << perl_namespace(program_) << service_name_ << "Client;" << '\n' << '\n' + << extends_client << '\n' << "use base qw(" << perl_namespace(program_) + << service_name_ << "If);" << '\n'; // Constructor function - f_service_ << "sub new {" << endl; + f_service_ << "sub new {" << '\n'; indent_up(); - f_service_ << indent() << "my ($classname, $input, $output) = @_;" << endl << indent() - << "my $self = {};" << endl; + f_service_ << indent() << "my ($classname, $input, $output) = @_;" << '\n' << indent() + << "my $self = {};" << '\n'; if (!extends.empty()) { - f_service_ << indent() << "$self = $classname->SUPER::new($input, $output);" << endl; + f_service_ << indent() << "$self = $classname->SUPER::new($input, $output);" << '\n'; } else { - f_service_ << indent() << "$self->{input} = $input;" << endl << indent() - << "$self->{output} = defined $output ? $output : $input;" << endl << indent() - << "$self->{seqid} = 0;" << endl; + f_service_ << indent() << "$self->{input} = $input;" << '\n' << indent() + << "$self->{output} = defined $output ? $output : $input;" << '\n' << indent() + << "$self->{seqid} = 0;" << '\n'; } - f_service_ << indent() << "return bless($self,$classname);" << endl; + f_service_ << indent() << "return bless($self,$classname);" << '\n'; indent_down(); - f_service_ << "}" << endl << endl; + f_service_ << "}" << '\n' << '\n'; // Generate client method implementations vector functions = tservice->get_functions(); @@ -1068,7 +1066,7 @@ void t_perl_generator::generate_service_client(t_service* tservice) { string funname = (*f_iter)->get_name(); // Open function - f_service_ << "sub " << function_signature(*f_iter) << endl; + f_service_ << "sub " << function_signature(*f_iter) << '\n'; indent_up(); @@ -1083,21 +1081,21 @@ void t_perl_generator::generate_service_client(t_service* tservice) { } f_service_ << "$" << (*fld_iter)->get_name(); } - f_service_ << ");" << endl; + f_service_ << ");" << '\n'; if (!(*f_iter)->is_oneway()) { f_service_ << indent(); if (!(*f_iter)->get_returntype()->is_void()) { f_service_ << "return "; } - f_service_ << "$self->recv_" << funname << "();" << endl; + f_service_ << "$self->recv_" << funname << "();" << '\n'; } indent_down(); - f_service_ << "}" << endl << endl; + f_service_ << "}" << '\n' << '\n'; - f_service_ << "sub send_" << function_signature(*f_iter) << endl; + f_service_ << "sub send_" << function_signature(*f_iter) << '\n'; indent_up(); @@ -1107,23 +1105,23 @@ void t_perl_generator::generate_service_client(t_service* tservice) { // Serialize the request header f_service_ << indent() << "$self->{output}->writeMessageBegin('" << (*f_iter)->get_name() << "', " << ((*f_iter)->is_oneway() ? "Thrift::TMessageType::ONEWAY" : "Thrift::TMessageType::CALL") - << ", $self->{seqid});" << endl; + << ", $self->{seqid});" << '\n'; - f_service_ << indent() << "my $args = " << argsname << "->new();" << endl; + f_service_ << indent() << "my $args = " << argsname << "->new();" << '\n'; for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) { f_service_ << indent() << "$args->{" << (*fld_iter)->get_name() << "} = $" - << (*fld_iter)->get_name() << ";" << endl; + << (*fld_iter)->get_name() << ";" << '\n'; } // Write to the stream - f_service_ << indent() << "$args->write($self->{output});" << endl << indent() - << "$self->{output}->writeMessageEnd();" << endl << indent() - << "$self->{output}->getTransport()->flush();" << endl; + f_service_ << indent() << "$args->write($self->{output});" << '\n' << indent() + << "$self->{output}->writeMessageEnd();" << '\n' << indent() + << "$self->{output}->getTransport()->flush();" << '\n'; indent_down(); - f_service_ << "}" << endl; + f_service_ << "}" << '\n'; if (!(*f_iter)->is_oneway()) { std::string resultname = perl_namespace(tservice->get_program()) + service_name_ + "_" @@ -1134,29 +1132,29 @@ void t_perl_generator::generate_service_client(t_service* tservice) { string("recv_") + (*f_iter)->get_name(), &noargs); // Open function - f_service_ << endl << "sub " << function_signature(&recv_function) << endl; + f_service_ << '\n' << "sub " << function_signature(&recv_function) << '\n'; indent_up(); - f_service_ << indent() << "my $rseqid = 0;" << endl << indent() << "my $fname;" << endl - << indent() << "my $mtype = 0;" << endl << endl; + f_service_ << indent() << "my $rseqid = 0;" << '\n' << indent() << "my $fname;" << '\n' + << indent() << "my $mtype = 0;" << '\n' << '\n'; f_service_ << indent() << "$self->{input}->readMessageBegin(\\$fname, \\$mtype, \\$rseqid);" - << endl << indent() << "if ($mtype == Thrift::TMessageType::EXCEPTION) {" << endl - << indent() << " my $x = Thrift::TApplicationException->new();" << endl << indent() - << " $x->read($self->{input});" << endl << indent() - << " $self->{input}->readMessageEnd();" << endl << indent() << " die $x;" << endl - << indent() << "}" << endl; + << '\n' << indent() << "if ($mtype == Thrift::TMessageType::EXCEPTION) {" << '\n' + << indent() << " my $x = Thrift::TApplicationException->new();" << '\n' << indent() + << " $x->read($self->{input});" << '\n' << indent() + << " $self->{input}->readMessageEnd();" << '\n' << indent() << " die $x;" << '\n' + << indent() << "}" << '\n'; - f_service_ << indent() << "my $result = " << resultname << "->new();" << endl << indent() - << "$result->read($self->{input});" << endl; + f_service_ << indent() << "my $result = " << resultname << "->new();" << '\n' << indent() + << "$result->read($self->{input});" << '\n'; - f_service_ << indent() << "$self->{input}->readMessageEnd();" << endl << endl; + f_service_ << indent() << "$self->{input}->readMessageEnd();" << '\n' << '\n'; // Careful, only return result if not a void function if (!(*f_iter)->get_returntype()->is_void()) { - f_service_ << indent() << "if (defined $result->{success} ) {" << endl << indent() - << " return $result->{success};" << endl << indent() << "}" << endl; + f_service_ << indent() << "if (defined $result->{success} ) {" << '\n' << indent() + << " return $result->{success};" << '\n' << indent() << "}" << '\n'; } t_struct* xs = (*f_iter)->get_xceptions(); @@ -1164,21 +1162,21 @@ void t_perl_generator::generate_service_client(t_service* tservice) { vector::const_iterator x_iter; for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { f_service_ << indent() << "if (defined $result->{" << (*x_iter)->get_name() << "}) {" - << endl << indent() << " die $result->{" << (*x_iter)->get_name() << "};" - << endl << indent() << "}" << endl; + << '\n' << indent() << " die $result->{" << (*x_iter)->get_name() << "};" + << '\n' << indent() << "}" << '\n'; } // Careful, only return _result if not a void function if ((*f_iter)->get_returntype()->is_void()) { - indent(f_service_) << "return;" << endl; + indent(f_service_) << "return;" << '\n'; } else { f_service_ << indent() << "die \"" << (*f_iter)->get_name() << " failed: unknown result\";" - << endl; + << '\n'; } // Close function indent_down(); - f_service_ << "}" << endl; + f_service_ << "}" << '\n'; } } } @@ -1244,7 +1242,7 @@ void t_perl_generator::generate_deserialize_field(ostream& out, } else if (type->is_enum()) { out << "readI32(\\$" << name << ");"; } - out << endl; + out << '\n'; } else { printf("DO NOT KNOW HOW TO DESERIALIZE FIELD '%s' TYPE '%s'\n", @@ -1263,8 +1261,8 @@ void t_perl_generator::generate_deserialize_struct(ostream& out, t_struct* tstruct, string prefix) { out << indent() << "$" << prefix << " = " << perl_namespace(tstruct->get_program()) - << tstruct->get_name() << "->new();" << endl << indent() << "$xfer += $" << prefix - << "->read($input);" << endl; + << tstruct->get_name() << "->new();" << '\n' << indent() << "$xfer += $" << prefix + << "->read($input);" << '\n'; } void t_perl_generator::generate_deserialize_container(ostream& out, t_type* ttype, string prefix) { @@ -1280,33 +1278,33 @@ void t_perl_generator::generate_deserialize_container(ostream& out, t_type* ttyp t_field fvtype(g_type_i8, vtype); t_field fetype(g_type_i8, etype); - out << indent() << "my $" << size << " = 0;" << endl; + out << indent() << "my $" << size << " = 0;" << '\n'; // Declare variables, read header if (ttype->is_map()) { - out << indent() << "$" << prefix << " = {};" << endl << indent() << "my $" << ktype << " = 0;" - << endl << indent() << "my $" << vtype << " = 0;" << endl; + out << indent() << "$" << prefix << " = {};" << '\n' << indent() << "my $" << ktype << " = 0;" + << '\n' << indent() << "my $" << vtype << " = 0;" << '\n'; out << indent() << "$xfer += $input->readMapBegin(" - << "\\$" << ktype << ", \\$" << vtype << ", \\$" << size << ");" << endl; + << "\\$" << ktype << ", \\$" << vtype << ", \\$" << size << ");" << '\n'; } else if (ttype->is_set()) { - out << indent() << "$" << prefix << " = {};" << endl << indent() << "my $" << etype << " = 0;" - << endl << indent() << "$xfer += $input->readSetBegin(" - << "\\$" << etype << ", \\$" << size << ");" << endl; + out << indent() << "$" << prefix << " = {};" << '\n' << indent() << "my $" << etype << " = 0;" + << '\n' << indent() << "$xfer += $input->readSetBegin(" + << "\\$" << etype << ", \\$" << size << ");" << '\n'; } else if (ttype->is_list()) { - out << indent() << "$" << prefix << " = [];" << endl << indent() << "my $" << etype << " = 0;" - << endl << indent() << "$xfer += $input->readListBegin(" - << "\\$" << etype << ", \\$" << size << ");" << endl; + out << indent() << "$" << prefix << " = [];" << '\n' << indent() << "my $" << etype << " = 0;" + << '\n' << indent() << "$xfer += $input->readListBegin(" + << "\\$" << etype << ", \\$" << size << ");" << '\n'; } // For loop iterates over elements string i = tmp("_i"); indent(out) << "for (my $" << i << " = 0; $" << i << " < $" << size << "; ++$" << i << ")" - << endl; + << '\n'; scope_up(out); @@ -1322,11 +1320,11 @@ void t_perl_generator::generate_deserialize_container(ostream& out, t_type* ttyp // Read container end if (ttype->is_map()) { - indent(out) << "$xfer += $input->readMapEnd();" << endl; + indent(out) << "$xfer += $input->readMapEnd();" << '\n'; } else if (ttype->is_set()) { - indent(out) << "$xfer += $input->readSetEnd();" << endl; + indent(out) << "$xfer += $input->readSetEnd();" << '\n'; } else if (ttype->is_list()) { - indent(out) << "$xfer += $input->readListEnd();" << endl; + indent(out) << "$xfer += $input->readListEnd();" << '\n'; } scope_down(out); @@ -1341,24 +1339,24 @@ void t_perl_generator::generate_deserialize_map_element(ostream& out, t_map* tma t_field fkey(tmap->get_key_type(), key); t_field fval(tmap->get_val_type(), val); - indent(out) << declare_field(&fkey, true, true) << endl; - indent(out) << declare_field(&fval, true, true) << endl; + indent(out) << declare_field(&fkey, true, true) << '\n'; + indent(out) << declare_field(&fval, true, true) << '\n'; generate_deserialize_field(out, &fkey); generate_deserialize_field(out, &fval); - indent(out) << "$" << prefix << "->{$" << key << "} = $" << val << ";" << endl; + indent(out) << "$" << prefix << "->{$" << key << "} = $" << val << ";" << '\n'; } void t_perl_generator::generate_deserialize_set_element(ostream& out, t_set* tset, string prefix) { string elem = tmp("elem"); t_field felem(tset->get_elem_type(), elem); - indent(out) << "my $" << elem << " = undef;" << endl; + indent(out) << "my $" << elem << " = undef;" << '\n'; generate_deserialize_field(out, &felem); - indent(out) << "$" << prefix << "->{$" << elem << "} = 1;" << endl; + indent(out) << "$" << prefix << "->{$" << elem << "} = 1;" << '\n'; } void t_perl_generator::generate_deserialize_list_element(ostream& out, @@ -1367,11 +1365,11 @@ void t_perl_generator::generate_deserialize_list_element(ostream& out, string elem = tmp("elem"); t_field felem(tlist->get_elem_type(), elem); - indent(out) << "my $" << elem << " = undef;" << endl; + indent(out) << "my $" << elem << " = undef;" << '\n'; generate_deserialize_field(out, &felem); - indent(out) << "push(@{$" << prefix << "},$" << elem << ");" << endl; + indent(out) << "push(@{$" << prefix << "},$" << elem << ");" << '\n'; } /** @@ -1435,7 +1433,7 @@ void t_perl_generator::generate_serialize_field(ostream& out, t_field* tfield, s } else if (type->is_enum()) { out << "writeI32($" << name << ");"; } - out << endl; + out << '\n'; } else { printf("DO NOT KNOW HOW TO SERIALIZE FIELD '%s%s' TYPE '%s'\n", @@ -1453,7 +1451,7 @@ void t_perl_generator::generate_serialize_field(ostream& out, t_field* tfield, s */ void t_perl_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix) { (void)tstruct; - indent(out) << "$xfer += $" << prefix << "->write($output);" << endl; + indent(out) << "$xfer += $" << prefix << "->write($output);" << '\n'; } /** @@ -1466,17 +1464,17 @@ void t_perl_generator::generate_serialize_container(ostream& out, t_type* ttype, indent(out) << "$xfer += $output->writeMapBegin(" << type_to_enum(((t_map*)ttype)->get_key_type()) << ", " << type_to_enum(((t_map*)ttype)->get_val_type()) << ", " - << "scalar(keys %{$" << prefix << "}));" << endl; + << "scalar(keys %{$" << prefix << "}));" << '\n'; } else if (ttype->is_set()) { indent(out) << "$xfer += $output->writeSetBegin(" << type_to_enum(((t_set*)ttype)->get_elem_type()) << ", " - << "scalar(@{$" << prefix << "}));" << endl; + << "scalar(@{$" << prefix << "}));" << '\n'; } else if (ttype->is_list()) { indent(out) << "$xfer += $output->writeListBegin(" << type_to_enum(((t_list*)ttype)->get_elem_type()) << ", " - << "scalar(@{$" << prefix << "}));" << endl; + << "scalar(@{$" << prefix << "}));" << '\n'; } scope_up(out); @@ -1485,7 +1483,7 @@ void t_perl_generator::generate_serialize_container(ostream& out, t_type* ttype, string kiter = tmp("kiter"); string viter = tmp("viter"); indent(out) << "while( my ($" << kiter << ",$" << viter << ") = each %{$" << prefix << "}) " - << endl; + << '\n'; scope_up(out); generate_serialize_map_element(out, (t_map*)ttype, kiter, viter); @@ -1493,14 +1491,14 @@ void t_perl_generator::generate_serialize_container(ostream& out, t_type* ttype, } else if (ttype->is_set()) { string iter = tmp("iter"); - indent(out) << "foreach my $" << iter << " (@{$" << prefix << "})" << endl; + indent(out) << "foreach my $" << iter << " (@{$" << prefix << "})" << '\n'; scope_up(out); generate_serialize_set_element(out, (t_set*)ttype, iter); scope_down(out); } else if (ttype->is_list()) { string iter = tmp("iter"); - indent(out) << "foreach my $" << iter << " (@{$" << prefix << "}) " << endl; + indent(out) << "foreach my $" << iter << " (@{$" << prefix << "}) " << '\n'; scope_up(out); generate_serialize_list_element(out, (t_list*)ttype, iter); scope_down(out); @@ -1509,11 +1507,11 @@ void t_perl_generator::generate_serialize_container(ostream& out, t_type* ttype, scope_down(out); if (ttype->is_map()) { - indent(out) << "$xfer += $output->writeMapEnd();" << endl; + indent(out) << "$xfer += $output->writeMapEnd();" << '\n'; } else if (ttype->is_set()) { - indent(out) << "$xfer += $output->writeSetEnd();" << endl; + indent(out) << "$xfer += $output->writeSetEnd();" << '\n'; } else if (ttype->is_list()) { - indent(out) << "$xfer += $output->writeListEnd();" << endl; + indent(out) << "$xfer += $output->writeListEnd();" << '\n'; } scope_down(out); diff --git a/compiler/cpp/src/thrift/generate/t_php_generator.cc b/compiler/cpp/src/thrift/generate/t_php_generator.cc index 83738586821..6879501db0f 100644 --- a/compiler/cpp/src/thrift/generate/t_php_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_php_generator.cc @@ -35,8 +35,6 @@ using std::string; using std::stringstream; using std::vector; -static const string endl = "\n"; // avoid ostream << std::endl flushes - #define NSGLOBAL (nsglobal_.size() ? nsglobal_ : "") #define NSGLOBAL_A ("\\" + NSGLOBAL) #define NSGLOBAL_B (NSGLOBAL + "\\") @@ -62,7 +60,7 @@ class t_php_generator : public t_oop_generator { validate_ = false; json_serializable_ = false; getters_setters_ = false; - + nsglobal_ = ""; // by default global namespace is empty classmap_ = false; for (iter = parsed_options.begin(); iter != parsed_options.end(); ++iter) { @@ -513,28 +511,28 @@ void t_php_generator::generate_typedef(t_typedef* ttypedef) { * Generates service header contains namespace suffix and includes inside file specified */ void t_php_generator::generate_service_header(t_service* tservice, std::ostream& file) { - file << "get_program()).empty()) { - file << "namespace " << php_namespace_suffix(tservice->get_program()) << ";" << endl - << endl; + file << "namespace " << php_namespace_suffix(tservice->get_program()) << ";" << '\n' + << '\n'; } file << autogen_comment() << php_includes(); - file << endl; + file << '\n'; } /** * Generates program header contains namespace suffix and includes inside file specified */ void t_php_generator::generate_program_header(std::ostream& file) { - file << "get_name() << endl - << "{" << endl; + f_enum << "final class " << tenum->get_name() << '\n' + << "{" << '\n'; indent_up(); for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) { int value = (*c_iter)->get_value(); generate_php_doc(f_enum, *c_iter); - indent(f_enum) << "const " << (*c_iter)->get_name() << " = " << value << ";" << endl - << endl; + indent(f_enum) << "const " << (*c_iter)->get_name() << " = " << value << ";" << '\n' + << '\n'; } - indent(f_enum) << "static public $__names = array(" << endl; + indent(f_enum) << "static public $__names = array(" << '\n'; indent_up(); for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) { int value = (*c_iter)->get_value(); - indent(f_enum) << value << " => '" << (*c_iter)->get_name() << "'," << endl; + indent(f_enum) << value << " => '" << (*c_iter)->get_name() << "'," << '\n'; } indent_down(); - indent(f_enum) << ");" << endl; + indent(f_enum) << ");" << '\n'; indent_down(); - f_enum << "}" << endl << endl; + f_enum << "}" << '\n' << '\n'; if (!classmap_) { f_enum.close(); } @@ -604,8 +602,8 @@ void t_php_generator::generate_consts(vector consts) { f_consts.open(f_consts_name.c_str()); generate_program_header(f_consts); } - f_consts << "final class Constant extends \\Thrift\\Type\\TConstant"<< endl - << "{" << endl; + f_consts << "final class Constant extends \\Thrift\\Type\\TConstant"<< '\n' + << "{" << '\n'; indent_up(); @@ -613,30 +611,30 @@ void t_php_generator::generate_consts(vector consts) { for (c_iter = consts.begin(); c_iter != consts.end(); ++c_iter) { string name = (*c_iter)->get_name(); - indent(f_consts) << "static protected $" << name << ";" << endl; + indent(f_consts) << "static protected $" << name << ";" << '\n'; } // Create init function for (c_iter = consts.begin(); c_iter != consts.end(); ++c_iter) { string name = (*c_iter)->get_name(); - f_consts << endl; + f_consts << '\n'; - f_consts << indent() << "protected static function init_" << name << "()" <get_type(), (*c_iter)->get_value()); - f_consts << ";" << endl; + f_consts << ";" << '\n'; indent_down(); - indent(f_consts) << "}" << endl; + indent(f_consts) << "}" << '\n'; } indent_down(); - f_consts << "}" << endl; + f_consts << "}" << '\n'; if (!classmap_) { f_consts.close(); } @@ -679,7 +677,7 @@ string t_php_generator::render_const_value(t_type* type, t_const_value* value) { } else if (type->is_enum()) { indent(out) << value->get_integer(); } else if (type->is_struct() || type->is_xception()) { - out << "new " << php_namespace(type->get_program()) << type->get_name() << "(array(" << endl; + out << "new " << php_namespace(type->get_program()) << type->get_name() << "(array(" << '\n'; indent_up(); const vector& fields = ((t_struct*)type)->get_members(); vector::const_iterator f_iter; @@ -699,14 +697,14 @@ string t_php_generator::render_const_value(t_type* type, t_const_value* value) { out << render_const_value(g_type_string, v_iter->first); out << " => "; out << render_const_value(field_type, v_iter->second); - out << "," << endl; + out << "," << '\n'; } indent_down(); indent(out) << "))"; } else if (type->is_map()) { t_type* ktype = ((t_map*)type)->get_key_type(); t_type* vtype = ((t_map*)type)->get_val_type(); - out << "array(" << endl; + out << "array(" << '\n'; indent_up(); const map& val = value->get_map(); map::const_iterator v_iter; @@ -715,7 +713,7 @@ string t_php_generator::render_const_value(t_type* type, t_const_value* value) { out << render_const_value(ktype, v_iter->first); out << " => "; out << render_const_value(vtype, v_iter->second); - out << "," << endl; + out << "," << '\n'; } indent_down(); indent(out) << ")"; @@ -726,7 +724,7 @@ string t_php_generator::render_const_value(t_type* type, t_const_value* value) { } else { etype = ((t_set*)type)->get_elem_type(); } - out << "array(" << endl; + out << "array(" << '\n'; indent_up(); const vector& val = value->get_list(); vector::const_iterator v_iter; @@ -736,7 +734,7 @@ string t_php_generator::render_const_value(t_type* type, t_const_value* value) { if (type->is_set()) { out << " => true"; } - out << "," << endl; + out << "," << '\n'; } indent_down(); indent(out) << ")"; @@ -779,27 +777,27 @@ void t_php_generator::generate_php_struct(t_struct* tstruct, bool is_exception) void t_php_generator::generate_php_type_spec(ostream& out, t_type* t) { t = get_true_type(t); - indent(out) << "'type' => " << type_to_enum(t) << "," << endl; + indent(out) << "'type' => " << type_to_enum(t) << "," << '\n'; if (t->is_base_type()) { // Noop, type is all we need } else if (t->is_struct() || t->is_xception() || t->is_enum()) { indent(out) << "'class' => '" << php_namespace(t->get_program()) << t->get_name() << "'," - << endl; + << '\n'; } else if (t->is_map()) { t_type* ktype = get_true_type(((t_map*)t)->get_key_type()); t_type* vtype = get_true_type(((t_map*)t)->get_val_type()); - indent(out) << "'ktype' => " << type_to_enum(ktype) << "," << endl; - indent(out) << "'vtype' => " << type_to_enum(vtype) << "," << endl; - indent(out) << "'key' => array(" << endl; + indent(out) << "'ktype' => " << type_to_enum(ktype) << "," << '\n'; + indent(out) << "'vtype' => " << type_to_enum(vtype) << "," << '\n'; + indent(out) << "'key' => array(" << '\n'; indent_up(); generate_php_type_spec(out, ktype); indent_down(); - indent(out) << ")," << endl; - indent(out) << "'val' => array(" << endl; + indent(out) << ")," << '\n'; + indent(out) << "'val' => array(" << '\n'; indent_up(); generate_php_type_spec(out, vtype); - indent(out) << ")," << endl; + indent(out) << ")," << '\n'; indent_down(); } else if (t->is_list() || t->is_set()) { t_type* etype; @@ -808,11 +806,11 @@ void t_php_generator::generate_php_type_spec(ostream& out, t_type* t) { } else { etype = get_true_type(((t_set*)t)->get_elem_type()); } - indent(out) << "'etype' => " << type_to_enum(etype) << "," << endl; - indent(out) << "'elem' => array(" << endl; + indent(out) << "'etype' => " << type_to_enum(etype) << "," << '\n'; + indent(out) << "'elem' => array(" << '\n'; indent_up(); generate_php_type_spec(out, etype); - indent(out) << ")," << endl; + indent(out) << ")," << '\n'; indent_down(); } else { throw "compiler error: no type for php struct spec field"; @@ -824,24 +822,24 @@ void t_php_generator::generate_php_type_spec(ostream& out, t_type* t) { * type information to generalize serialization routines. */ void t_php_generator::generate_php_struct_spec(ostream& out, t_struct* tstruct) { - indent(out) << "static public $_TSPEC = array(" << endl; + indent(out) << "static public $_TSPEC = array(" << '\n'; indent_up(); const vector& members = tstruct->get_members(); vector::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()); - indent(out) << (*m_iter)->get_key() << " => array(" << endl; + indent(out) << (*m_iter)->get_key() << " => array(" << '\n'; indent_up(); - out << indent() << "'var' => '" << (*m_iter)->get_name() << "'," << endl; - out << indent() << "'isRequired' => " << ((*m_iter)->get_req() == t_field::T_REQUIRED ? "true" : "false") << "," << endl; + out << indent() << "'var' => '" << (*m_iter)->get_name() << "'," << '\n'; + out << indent() << "'isRequired' => " << ((*m_iter)->get_req() == t_field::T_REQUIRED ? "true" : "false") << "," << '\n'; generate_php_type_spec(out, t); indent_down(); - indent(out) << ")," << endl; + indent(out) << ")," << '\n'; } indent_down(); - indent(out) << ");" << endl << endl; + indent(out) << ");" << '\n' << '\n'; } /** * Generates necessary accessors and mutators for the fields @@ -865,10 +863,10 @@ void t_php_generator::generate_generic_field_getters_setters(std::ostream& out, indent_down(); } - indent(out) << endl; + indent(out) << '\n'; out << getter_stream.str(); out << setter_stream.str(); - indent(out) << endl; + indent(out) << '\n'; } /** * Generates a getter for the generated private fields @@ -878,16 +876,16 @@ void t_php_generator::generate_reflection_getters(ostringstream& out, string cap_name) { - out << indent() << "public function " << "get" << cap_name << "()" << endl - << indent() << "{" << endl; + out << indent() << "public function " << "get" << cap_name << "()" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "return $this->" << field_name << ";" << endl; + out << indent() << "return $this->" << field_name << ";" << '\n'; indent_down(); - out << indent() << "}" << endl; - out << endl; + out << indent() << "}" << '\n'; + out << '\n'; } /** * Generates a setter for the generated private fields @@ -896,17 +894,17 @@ void t_php_generator::generate_reflection_setters(ostringstream& out, string field_name, string cap_name) { - out << indent() << "public function set" << cap_name << "(" << "$" << field_name << ")" << endl - << indent() << "{" << endl; + out << indent() << "public function set" << cap_name << "(" << "$" << field_name << ")" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "$this->" << field_name << " = $" << field_name << ";" << endl; + out << indent() << "$this->" << field_name << " = $" << field_name << ";" << '\n'; indent_down(); - out << indent() << "}" << endl; - out << endl; + out << indent() << "}" << '\n'; + out << '\n'; } /** * Gets the first-letter capitalized name for the field @@ -943,11 +941,11 @@ void t_php_generator::generate_php_struct_definition(ostream& out, if (json_serializable_) { out << " implements JsonSerializable"; } - out << endl - << "{" << endl; + out << '\n' + << "{" << '\n'; indent_up(); - out << indent() << "static public $isValidate = " << (validate_ ? "true" : "false") << ";" << endl << endl; + out << indent() << "static public $isValidate = " << (validate_ ? "true" : "false") << ";" << '\n' << '\n'; generate_php_struct_spec(out, tstruct); @@ -959,15 +957,15 @@ void t_php_generator::generate_php_struct_definition(ostream& out, } generate_php_doc(out, *m_iter); string access = (getters_setters_) ? "private" : "public"; - indent(out) << access << " $" << (*m_iter)->get_name() << " = " << dval << ";" << endl; + indent(out) << access << " $" << (*m_iter)->get_name() << " = " << dval << ";" << '\n'; } - out << endl; + out << '\n'; // Generate constructor from array string param = (members.size() > 0) ? "$vals = null" : ""; - out << indent() << "public function __construct(" << param << ")"<< endl - << indent() << "{" << endl; + out << indent() << "public function __construct(" << param << ")"<< '\n' + << indent() << "{" << '\n'; indent_up(); if (members.size() > 0) { @@ -975,62 +973,62 @@ void t_php_generator::generate_php_struct_definition(ostream& out, t_type* t = get_true_type((*m_iter)->get_type()); if ((*m_iter)->get_value() != nullptr && (t->is_struct() || t->is_xception())) { indent(out) << "$this->" << (*m_iter)->get_name() << " = " - << render_const_value(t, (*m_iter)->get_value()) << ";" << endl; + << render_const_value(t, (*m_iter)->get_value()) << ";" << '\n'; } } - out << indent() << "if (is_array($vals)) {" << endl; + out << indent() << "if (is_array($vals)) {" << '\n'; indent_up(); if (oop_) { - out << indent() << "parent::__construct(self::$_TSPEC, $vals);" << endl; + out << indent() << "parent::__construct(self::$_TSPEC, $vals);" << '\n'; } else { for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { - out << indent() << "if (isset($vals['" << (*m_iter)->get_name() << "'])) {" << endl; + out << indent() << "if (isset($vals['" << (*m_iter)->get_name() << "'])) {" << '\n'; indent_up(); out << indent() << "$this->" << (*m_iter)->get_name() << " = $vals['" - << (*m_iter)->get_name() << "'];" << endl; + << (*m_iter)->get_name() << "'];" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } } indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } scope_down(out); - out << endl; + out << '\n'; - out << indent() << "public function getName()" << endl - << indent() << "{" << endl; + out << indent() << "public function getName()" << '\n' + << indent() << "{" << '\n'; indent_up(); - out << indent() << "return '" << tstruct->get_name() << "';" << endl; + out << indent() << "return '" << tstruct->get_name() << "';" << '\n'; indent_down(); - out << indent() << "}" << endl << endl; + out << indent() << "}" << '\n' << '\n'; - out << endl; + out << '\n'; if (getters_setters_) { generate_generic_field_getters_setters(out, tstruct); } generate_php_struct_reader(out, tstruct, is_result); - out << endl; + out << '\n'; generate_php_struct_writer(out, tstruct, is_result); if (needs_php_read_validator(tstruct, is_result)) { - out << endl; + out << '\n'; generate_php_struct_read_validator(out, tstruct); } if (needs_php_write_validator(tstruct, is_result)) { - out << endl; + out << '\n'; generate_php_struct_write_validator(out, tstruct); } if (json_serializable_) { - out << endl; + out << '\n'; generate_php_struct_json_serialize(out, tstruct, is_result); } indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } /** @@ -1040,34 +1038,34 @@ void t_php_generator::generate_php_struct_reader(ostream& out, t_struct* tstruct const vector& fields = tstruct->get_members(); vector::const_iterator f_iter; - indent(out) << "public function read($input)" << endl; + indent(out) << "public function read($input)" << '\n'; scope_up(out); if (oop_) { if (needs_php_read_validator(tstruct, is_result)) { indent(out) << "$tmp = $this->_read('" << tstruct->get_name() << "', self::$_TSPEC, $input);" - << endl; - indent(out) << "$this->_validateForRead();" << endl; - indent(out) << "return $tmp;" << endl; + << '\n'; + indent(out) << "$this->_validateForRead();" << '\n'; + indent(out) << "return $tmp;" << '\n'; } else { indent(out) << "return $this->_read('" << tstruct->get_name() << "', self::$_TSPEC, $input);" - << endl; + << '\n'; } scope_down(out); - out << endl; + out << '\n'; return; } - out << indent() << "$xfer = 0;" << endl << indent() << "$fname = null;" << endl << indent() - << "$ftype = 0;" << endl << indent() << "$fid = 0;" << endl; + out << indent() << "$xfer = 0;" << '\n' << indent() << "$fname = null;" << '\n' << indent() + << "$ftype = 0;" << '\n' << indent() << "$fid = 0;" << '\n'; // Declare stack tmp variables if (!binary_inline_) { - indent(out) << "$xfer += $input->readStructBegin($fname);" << endl; + indent(out) << "$xfer += $input->readStructBegin($fname);" << '\n'; } // Loop over reading in fields - indent(out) << "while (true) {" << endl; + indent(out) << "while (true) {" << '\n'; indent_up(); @@ -1077,80 +1075,80 @@ void t_php_generator::generate_php_struct_reader(ostream& out, t_struct* tstruct t_field ffid(g_type_i16, "fid"); generate_deserialize_field(out, &fftype); out << indent() << "if ($ftype == " - << "TType::STOP) {" << endl << indent() << " break;" << endl << indent() << "}" << endl; + << "TType::STOP) {" << '\n' << indent() << " break;" << '\n' << indent() << "}" << '\n'; generate_deserialize_field(out, &ffid); } else { - indent(out) << "$xfer += $input->readFieldBegin($fname, $ftype, $fid);" << endl; + indent(out) << "$xfer += $input->readFieldBegin($fname, $ftype, $fid);" << '\n'; // Check for field STOP marker and break indent(out) << "if ($ftype == " - << "TType::STOP) {" << endl; + << "TType::STOP) {" << '\n'; indent_up(); - indent(out) << "break;" << endl; + indent(out) << "break;" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } // Switch statement on the field we are reading - indent(out) << "switch ($fid) {" << endl; + indent(out) << "switch ($fid) {" << '\n'; indent_up(); // 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(out) << "case " << (*f_iter)->get_key() << ":" << '\n'; indent_up(); - indent(out) << "if ($ftype == " << type_to_enum((*f_iter)->get_type()) << ") {" << endl; + indent(out) << "if ($ftype == " << type_to_enum((*f_iter)->get_type()) << ") {" << '\n'; indent_up(); generate_deserialize_field(out, *f_iter, "this->"); indent_down(); - out << indent() << "} else {" << endl; + out << indent() << "} else {" << '\n'; indent_up(); if (binary_inline_) { - indent(out) << "$xfer += TProtocol::skipBinary($input, $ftype);" << endl; + indent(out) << "$xfer += TProtocol::skipBinary($input, $ftype);" << '\n'; } else { - indent(out) << "$xfer += $input->skip($ftype);" << endl; + indent(out) << "$xfer += $input->skip($ftype);" << '\n'; } indent_down(); - out << indent() << "}" << endl << indent() << "break;" << endl; + out << indent() << "}" << '\n' << indent() << "break;" << '\n'; indent_down(); } // In the default case we skip the field - indent(out) << "default:" << endl; + indent(out) << "default:" << '\n'; indent_up(); if (binary_inline_) { indent(out) << "$xfer += " - << "TProtocol::skipBinary($input, $ftype);" << endl; + << "TProtocol::skipBinary($input, $ftype);" << '\n'; } else { - indent(out) << "$xfer += $input->skip($ftype);" << endl; + indent(out) << "$xfer += $input->skip($ftype);" << '\n'; } - indent(out) << "break;" << endl; + indent(out) << "break;" << '\n'; indent_down(); scope_down(out); if (!binary_inline_) { // Read field end marker - indent(out) << "$xfer += $input->readFieldEnd();" << endl; + indent(out) << "$xfer += $input->readFieldEnd();" << '\n'; } scope_down(out); if (!binary_inline_) { - indent(out) << "$xfer += $input->readStructEnd();" << endl; + indent(out) << "$xfer += $input->readStructEnd();" << '\n'; } if (needs_php_read_validator(tstruct, is_result)) { - indent(out) << "$this->_validateForRead();" << endl; + indent(out) << "$this->_validateForRead();" << '\n'; } - indent(out) << "return $xfer;" << endl; + indent(out) << "return $xfer;" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } /** @@ -1162,33 +1160,33 @@ void t_php_generator::generate_php_struct_writer(ostream& out, t_struct* tstruct vector::const_iterator f_iter; if (binary_inline_) { - indent(out) << "public function write(&$output)" << endl; + indent(out) << "public function write(&$output)" << '\n'; } else { - indent(out) << "public function write($output)" << endl; + indent(out) << "public function write($output)" << '\n'; } - indent(out) << "{" << endl; + indent(out) << "{" << '\n'; indent_up(); if (needs_php_write_validator(tstruct, is_result)) { - indent(out) << "$this->_validateForWrite();" << endl; + indent(out) << "$this->_validateForWrite();" << '\n'; } if (oop_) { indent(out) << "return $this->_write('" << tstruct->get_name() << "', self::$_TSPEC, $output);" - << endl; + << '\n'; scope_down(out); - out << endl; + out << '\n'; return; } - indent(out) << "$xfer = 0;" << endl; + indent(out) << "$xfer = 0;" << '\n'; if (!binary_inline_) { - indent(out) << "$xfer += $output->writeStructBegin('" << name << "');" << endl; + indent(out) << "$xfer += $output->writeStructBegin('" << name << "');" << '\n'; } for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { - out << indent() << "if ($this->" << (*f_iter)->get_name() << " !== null) {" << endl; + out << indent() << "if ($this->" << (*f_iter)->get_name() << " !== null) {" << '\n'; indent_up(); t_type* type = get_true_type((*f_iter)->get_type()); @@ -1200,22 +1198,22 @@ void t_php_generator::generate_php_struct_writer(ostream& out, t_struct* tstruct } if (!expect.empty()) { out << indent() << "if (!is_" << expect << "($this->" << (*f_iter)->get_name() << ")) {" - << endl; + << '\n'; indent_up(); out << indent() << "throw new " << "TProtocolException('Bad type in structure.', " - << "TProtocolException::INVALID_DATA);" << endl; + << "TProtocolException::INVALID_DATA);" << '\n'; scope_down(out); } // Write field header if (binary_inline_) { out << indent() << "$output .= pack('c', " << type_to_enum((*f_iter)->get_type()) << ");" - << endl << indent() << "$output .= pack('n', " << (*f_iter)->get_key() << ");" << endl; + << '\n' << indent() << "$output .= pack('n', " << (*f_iter)->get_key() << ");" << '\n'; } else { indent(out) << "$xfer += $output->writeFieldBegin(" << "'" << (*f_iter)->get_name() << "', " << type_to_enum((*f_iter)->get_type()) - << ", " << (*f_iter)->get_key() << ");" << endl; + << ", " << (*f_iter)->get_key() << ");" << '\n'; } // Write field contents @@ -1223,25 +1221,25 @@ void t_php_generator::generate_php_struct_writer(ostream& out, t_struct* tstruct // Write field closer if (!binary_inline_) { - indent(out) << "$xfer += $output->writeFieldEnd();" << endl; + indent(out) << "$xfer += $output->writeFieldEnd();" << '\n'; } indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } if (binary_inline_) { out << indent() << "$output .= pack('c', " - << "TType::STOP);" << endl; + << "TType::STOP);" << '\n'; } else { - out << indent() << "$xfer += $output->writeFieldStop();" << endl << indent() - << "$xfer += $output->writeStructEnd();" << endl; + out << indent() << "$xfer += $output->writeFieldStop();" << '\n' << indent() + << "$xfer += $output->writeStructEnd();" << '\n'; } - out << indent() << "return $xfer;" << endl; + out << indent() << "return $xfer;" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } void t_php_generator::generate_php_struct_read_validator(ostream& out, t_struct* tstruct) { @@ -1256,7 +1254,7 @@ void t_php_generator::generate_php_struct_required_validator(ostream& out, t_struct* tstruct, std::string method_name, bool write_mode) { - indent(out) << "private function " << method_name << "() {" << endl; + indent(out) << "private function " << method_name << "() {" << '\n'; indent_up(); const vector& fields = tstruct->get_members(); @@ -1268,32 +1266,32 @@ void t_php_generator::generate_php_struct_required_validator(ostream& out, t_field* field = (*f_iter); if (field->get_req() == t_field::T_REQUIRED || (field->get_req() == t_field::T_OPT_IN_REQ_OUT && write_mode)) { - indent(out) << "if ($this->" << field->get_name() << " === null) {" << endl; + indent(out) << "if ($this->" << field->get_name() << " === null) {" << '\n'; indent_up(); indent(out) << "throw new TProtocolException('Required field " << tstruct->get_name() << "." - << field->get_name() << " is unset!');" << endl; + << field->get_name() << " is unset!');" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } } } indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } void t_php_generator::generate_php_struct_json_serialize(ostream& out, t_struct* tstruct, bool is_result) { - indent(out) << "#[\\ReturnTypeWillChange]" << endl; - indent(out) << "public function jsonSerialize() {" << endl; + indent(out) << "#[\\ReturnTypeWillChange]" << '\n'; + indent(out) << "public function jsonSerialize() {" << '\n'; indent_up(); if (needs_php_write_validator(tstruct, is_result)) { - indent(out) << "$this->_validateForWrite();" << endl; + indent(out) << "$this->_validateForWrite();" << '\n'; } - indent(out) << "$json = new stdClass;" << endl; + indent(out) << "$json = new stdClass;" << '\n'; const vector& fields = tstruct->get_members(); @@ -1312,7 +1310,7 @@ void t_php_generator::generate_php_struct_json_serialize(ostream& out, continue; } } - indent(out) << "if ($this->" << name << " !== null) {" << endl; + indent(out) << "if ($this->" << name << " !== null) {" << '\n'; indent_up(); indent(out) << "$json->" << name << " = "; if (type->is_map()) { @@ -1320,16 +1318,16 @@ void t_php_generator::generate_php_struct_json_serialize(ostream& out, } else { out << type_to_cast(type); } - out << "$this->" << name << ";" << endl; + out << "$this->" << name << ";" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } } - indent(out) << "return $json;" << endl; + indent(out) << "return $json;" << '\n'; indent_down(); - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } int t_php_generator::get_php_num_required_fields(const vector& fields, bool write_mode) { @@ -1382,7 +1380,7 @@ void t_php_generator::generate_service(t_service* tservice) { if(classmap_) { // Close service file - f_service_ << endl; + f_service_ << '\n'; f_service_.close(); } } @@ -1413,34 +1411,34 @@ void t_php_generator::generate_service_processor(t_service* tservice) { } // Generate the header portion - f_service_processor << "class " << service_name_ << "Processor" << extends_processor << endl - << "{" << endl; + f_service_processor << "class " << service_name_ << "Processor" << extends_processor << '\n' + << "{" << '\n'; indent_up(); if (extends.empty()) { - f_service_processor << indent() << "protected $handler_ = null;" << endl; + f_service_processor << indent() << "protected $handler_ = null;" << '\n'; } - f_service_processor << indent() << "public function __construct($handler)"<< endl - << indent() << "{" << endl; + f_service_processor << indent() << "public function __construct($handler)"<< '\n' + << indent() << "{" << '\n'; indent_up(); if (extends.empty()) { - f_service_processor << indent() << "$this->handler_ = $handler;" << endl; + f_service_processor << indent() << "$this->handler_ = $handler;" << '\n'; } else { - f_service_processor << indent() << "parent::__construct($handler);" << endl; + f_service_processor << indent() << "parent::__construct($handler);" << '\n'; } indent_down(); - f_service_processor << indent() << "}" << endl << endl; + f_service_processor << indent() << "}" << '\n' << '\n'; // Generate the server implementation - f_service_processor << indent() << "public function process($input, $output)" << endl - << indent() << "{" << endl; + f_service_processor << indent() << "public function process($input, $output)" << '\n' + << indent() << "{" << '\n'; indent_up(); - f_service_processor << indent() << "$rseqid = 0;" << endl << indent() << "$fname = null;" << endl - << indent() << "$mtype = 0;" << endl << endl; + f_service_processor << indent() << "$rseqid = 0;" << '\n' << indent() << "$fname = null;" << '\n' + << indent() << "$mtype = 0;" << '\n' << '\n'; if (binary_inline_) { t_field ffname(g_type_string, "fname"); @@ -1450,36 +1448,36 @@ void t_php_generator::generate_service_processor(t_service* tservice) { generate_deserialize_field(f_service_processor, &fmtype, "", true); generate_deserialize_field(f_service_processor, &fseqid, "", true); } else { - f_service_processor << indent() << "$input->readMessageBegin($fname, $mtype, $rseqid);" << endl; + f_service_processor << indent() << "$input->readMessageBegin($fname, $mtype, $rseqid);" << '\n'; } // HOT: check for method implementation - f_service_processor << indent() << "$methodname = 'process_'.$fname;" << endl - << indent() << "if (!method_exists($this, $methodname)) {" << endl; + f_service_processor << indent() << "$methodname = 'process_'.$fname;" << '\n' + << indent() << "if (!method_exists($this, $methodname)) {" << '\n'; indent_up(); if (binary_inline_) { - f_service_processor << indent() << "throw new \\Exception('Function '.$fname.' not implemented.');" << endl; + f_service_processor << indent() << "throw new \\Exception('Function '.$fname.' not implemented.');" << '\n'; } else { f_service_processor << indent() << " $input->skip(" - << "TType::STRUCT);" << endl << indent() << " $input->readMessageEnd();" << endl + << "TType::STRUCT);" << '\n' << indent() << " $input->readMessageEnd();" << '\n' << indent() << " $x = new " << "TApplicationException('Function '.$fname.' not implemented.', " - << "TApplicationException::UNKNOWN_METHOD);" << endl << indent() + << "TApplicationException::UNKNOWN_METHOD);" << '\n' << indent() << " $output->writeMessageBegin($fname, " - << "TMessageType::EXCEPTION, $rseqid);" << endl << indent() - << " $x->write($output);" << endl << indent() << " $output->writeMessageEnd();" - << endl << indent() << " $output->getTransport()->flush();" << endl << indent() - << " return;" << endl; + << "TMessageType::EXCEPTION, $rseqid);" << '\n' << indent() + << " $x->write($output);" << '\n' << indent() << " $output->writeMessageEnd();" + << '\n' << indent() << " $output->getTransport()->flush();" << '\n' << indent() + << " return;" << '\n'; } indent_down(); - f_service_processor << indent() << "}" << endl - << indent() << "$this->$methodname($rseqid, $input, $output);" << endl - << indent() << "return true;" << endl; + f_service_processor << indent() << "}" << '\n' + << indent() << "$this->$methodname($rseqid, $input, $output);" << '\n' + << indent() << "return true;" << '\n'; indent_down(); - f_service_processor << indent() << "}" << endl << endl; + f_service_processor << indent() << "}" << '\n' << '\n'; // Generate the process subfunctions for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { @@ -1487,7 +1485,7 @@ void t_php_generator::generate_service_processor(t_service* tservice) { } indent_down(); - f_service_processor << "}" << endl; + f_service_processor << "}" << '\n'; if (!classmap_) { f_service_processor.close(); @@ -1501,8 +1499,8 @@ void t_php_generator::generate_service_processor(t_service* tservice) { */ void t_php_generator::generate_process_function(std::ostream& out, t_service* tservice, t_function* tfunction) { // Open function - out << indent() << "protected function process_" << tfunction->get_name() << "($seqid, $input, $output)" << endl - << indent() << "{" << endl; + out << indent() << "protected function process_" << tfunction->get_name() << "($seqid, $input, $output)" << '\n' + << indent() << "{" << '\n'; indent_up(); string argsname = php_namespace(tservice->get_program()) + service_name_ + "_" @@ -1512,32 +1510,32 @@ void t_php_generator::generate_process_function(std::ostream& out, t_service* ts out << indent() << "$bin_accel = ($input instanceof " << "TBinaryProtocolAccelerated) && function_exists('thrift_protocol_read_binary_after_message_begin');" - << endl; - out << indent() << "if ($bin_accel) {" << endl; + << '\n'; + out << indent() << "if ($bin_accel) {" << '\n'; indent_up(); - out << indent() << "$args = thrift_protocol_read_binary_after_message_begin(" <isStrictRead()" <isStrictRead()" << '\n'; indent_down(); - out << indent() <<");" << endl; + out << indent() <<");" << '\n'; indent_down(); - out << indent() << "} else {" << endl; + out << indent() << "} else {" << '\n'; indent_up(); - out << indent() << "$args = new " << argsname << "();" << endl - << indent() << "$args->read($input);" << endl; + out << indent() << "$args = new " << argsname << "();" << '\n' + << indent() << "$args->read($input);" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; if (!binary_inline_) { - out << indent() << "$input->readMessageEnd();" << endl; + out << indent() << "$input->readMessageEnd();" << '\n'; } t_struct* xs = tfunction->get_xceptions(); @@ -1546,12 +1544,12 @@ void t_php_generator::generate_process_function(std::ostream& out, t_service* ts // Declare result for non oneway function if (!tfunction->is_oneway()) { - out << indent() << "$result = new " << resultname << "();" << endl; + out << indent() << "$result = new " << resultname << "();" << '\n'; } // Try block for a function with exceptions if (xceptions.size() > 0) { - out << indent() << "try {" << endl; + out << indent() << "try {" << '\n'; indent_up(); } @@ -1574,7 +1572,7 @@ void t_php_generator::generate_process_function(std::ostream& out, t_service* ts } out << "$args->" << (*f_iter)->get_name(); } - out << ");" << endl; + out << ");" << '\n'; if (!tfunction->is_oneway() && xceptions.size() > 0) { indent_down(); @@ -1582,70 +1580,70 @@ void t_php_generator::generate_process_function(std::ostream& out, t_service* ts out << indent() << "} catch (" << php_namespace(get_true_type((*x_iter)->get_type())->get_program()) << (*x_iter)->get_type()->get_name() << " $" << (*x_iter)->get_name() << ") {" - << endl; + << '\n'; if (!tfunction->is_oneway()) { indent_up(); out << indent() << "$result->" << (*x_iter)->get_name() << " = $" - << (*x_iter)->get_name() << ";" << endl; + << (*x_iter)->get_name() << ";" << '\n'; indent_down(); out << indent(); } } - out << "}" << endl; + out << "}" << '\n'; } // Shortcut out here for oneway functions if (tfunction->is_oneway()) { - out << indent() << "return;" << endl; + out << indent() << "return;" << '\n'; indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; return; } out << indent() << "$bin_accel = ($output instanceof " << "TBinaryProtocolAccelerated) && function_exists('thrift_protocol_write_binary');" - << endl; + << '\n'; - out << indent() << "if ($bin_accel) {" << endl; + out << indent() << "if ($bin_accel) {" << '\n'; indent_up(); - out << indent() << "thrift_protocol_write_binary(" << endl; + out << indent() << "thrift_protocol_write_binary(" << '\n'; indent_up(); - out << indent() << "$output,"<get_name()<< "'," <isStrictWrite()"<get_name()<< "'," << '\n' + << indent() << "TMessageType::REPLY,"<< '\n' + << indent() << "$result," << '\n' + << indent() << "$seqid," << '\n' + << indent() << "$output->isStrictWrite()"<< '\n'; indent_down(); - out << indent() << ");" << endl; + out << indent() << ");" << '\n'; indent_down(); - out << indent() << "} else {" << endl; + out << indent() << "} else {" << '\n'; indent_up(); // Serialize the request header if (binary_inline_) { out << indent() << "$buff = pack('N', (0x80010000 | " - << "TMessageType::REPLY)); " << endl << indent() << "$buff .= pack('N', strlen('" - << tfunction->get_name() << "'));" << endl << indent() << "$buff .= '" - << tfunction->get_name() << "';" << endl << indent() << "$buff .= pack('N', $seqid);" - << endl << indent() << "$result->write($buff);" << endl << indent() - << "$output->write($buff);" << endl << indent() << "$output->flush();" << endl; + << "TMessageType::REPLY)); " << '\n' << indent() << "$buff .= pack('N', strlen('" + << tfunction->get_name() << "'));" << '\n' << indent() << "$buff .= '" + << tfunction->get_name() << "';" << '\n' << indent() << "$buff .= pack('N', $seqid);" + << '\n' << indent() << "$result->write($buff);" << '\n' << indent() + << "$output->write($buff);" << '\n' << indent() << "$output->flush();" << '\n'; } else { out << indent() << "$output->writeMessageBegin('" << tfunction->get_name() << "', " - << "TMessageType::REPLY, $seqid);" << endl << indent() << "$result->write($output);" - << endl << indent() << "$output->writeMessageEnd();" << endl << indent() - << "$output->getTransport()->flush();" << endl; + << "TMessageType::REPLY, $seqid);" << '\n' << indent() << "$result->write($output);" + << '\n' << indent() << "$output->writeMessageEnd();" << '\n' << indent() + << "$output->getTransport()->flush();" << '\n'; } scope_down(out); // Close function indent_down(); - out << indent() << "}" << endl; + out << indent() << "}" << '\n'; } /** @@ -1659,7 +1657,7 @@ void t_php_generator::generate_service_helpers(t_service* tservice) { ofstream_with_content_based_conditional_update& f_struct_definition = f_service_; if (classmap_) { - f_struct_definition << "// HELPER FUNCTIONS AND STRUCTURES" << endl << endl; + f_struct_definition << "// HELPER FUNCTIONS AND STRUCTURES" << '\n' << '\n'; } for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { @@ -1738,18 +1736,18 @@ void t_php_generator::generate_service_interface(t_service* tservice) { + tservice->get_extends()->get_name() + "If"; } generate_php_doc(f_service_interface, tservice); - f_service_interface << "interface " << php_namespace_declaration(tservice) << "If" << extends_if << endl - << "{" << endl; + f_service_interface << "interface " << php_namespace_declaration(tservice) << "If" << extends_if << '\n' + << "{" << '\n'; indent_up(); vector functions = tservice->get_functions(); vector::iterator f_iter; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { generate_php_doc(f_service_interface, *f_iter); - indent(f_service_interface) << "public function " << function_signature(*f_iter) << ";" << endl; + indent(f_service_interface) << "public function " << function_signature(*f_iter) << ";" << '\n'; } indent_down(); - f_service_interface << "}" << endl; + f_service_interface << "}" << '\n'; // Close service interface file if (!classmap_) { @@ -1776,21 +1774,21 @@ void t_php_generator::generate_service_rest(t_service* tservice) { extends_if = " extends " + php_namespace(tservice->get_extends()->get_program()) + tservice->get_extends()->get_name() + "Rest"; } - f_service_rest << "class " << service_name_ << "Rest" << extends_if << endl - << "{" << endl; + f_service_rest << "class " << service_name_ << "Rest" << extends_if << '\n' + << "{" << '\n'; indent_up(); if (extends.empty()) { - f_service_rest << indent() << "protected $impl_;" << endl << endl; + f_service_rest << indent() << "protected $impl_;" << '\n' << '\n'; } - f_service_rest << indent() << "public function __construct($impl) {" << endl << indent() - << " $this->impl_ = $impl;" << endl << indent() << "}" << endl << endl; + f_service_rest << indent() << "public function __construct($impl) {" << '\n' << indent() + << " $this->impl_ = $impl;" << '\n' << indent() << "}" << '\n' << '\n'; vector functions = tservice->get_functions(); vector::iterator f_iter; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { - indent(f_service_rest) << "public function " << (*f_iter)->get_name() << "($request) {" << endl; + indent(f_service_rest) << "public function " << (*f_iter)->get_name() << "($request) {" << '\n'; indent_up(); const vector& args = (*f_iter)->get_arglist()->get_members(); vector::const_iterator a_iter; @@ -1800,39 +1798,39 @@ void t_php_generator::generate_service_rest(t_service* tservice) { string req = "$request['" + (*a_iter)->get_name() + "']"; if (atype->is_bool()) { f_service_rest << indent() << "$" << (*a_iter)->get_name() << " = " << cast << "(!empty(" << req - << ") && (" << req << " !== 'false'));" << endl; + << ") && (" << req << " !== 'false'));" << '\n'; } else { f_service_rest << indent() << "$" << (*a_iter)->get_name() << " = isset(" << req << ") ? " - << cast << req << " : null;" << endl; + << cast << req << " : null;" << '\n'; } /* slist no longer supported if (atype->is_string() && ((t_base_type*)atype)->is_string_list()) { f_service_rest << indent() << "$" << (*a_iter)->get_name() << " = explode(',', $" - << (*a_iter)->get_name() << ");" << endl; + << (*a_iter)->get_name() << ");" << '\n'; } else */ if (atype->is_map() || atype->is_list()) { f_service_rest << indent() << "$" << (*a_iter)->get_name() << " = json_decode($" - << (*a_iter)->get_name() << ", true);" << endl; + << (*a_iter)->get_name() << ", true);" << '\n'; } else if (atype->is_set()) { f_service_rest << indent() << "$" << (*a_iter)->get_name() << " = array_fill_keys(json_decode($" - << (*a_iter)->get_name() << ", true), 1);" << endl; + << (*a_iter)->get_name() << ", true), 1);" << '\n'; } else if (atype->is_struct() || atype->is_xception()) { - f_service_rest << indent() << "if ($" << (*a_iter)->get_name() << " !== null) {" << endl + f_service_rest << indent() << "if ($" << (*a_iter)->get_name() << " !== null) {" << '\n' << indent() << " $" << (*a_iter)->get_name() << " = new " << php_namespace(atype->get_program()) << atype->get_name() << "(json_decode($" - << (*a_iter)->get_name() << ", true));" << endl << indent() << "}" << endl; + << (*a_iter)->get_name() << ", true));" << '\n' << indent() << "}" << '\n'; } } f_service_rest << indent() << "return $this->impl_->" << (*f_iter)->get_name() << "(" - << argument_list((*f_iter)->get_arglist(), false) << ");" << endl; + << argument_list((*f_iter)->get_arglist(), false) << ");" << '\n'; indent_down(); - indent(f_service_rest) << "}" << endl << endl; + indent(f_service_rest) << "}" << '\n' << '\n'; } indent_down(); - f_service_rest << "}" << endl << endl; + f_service_rest << "}" << '\n' << '\n'; // Close service rest file - f_service_rest << endl; + f_service_rest << '\n'; if (!classmap_) { f_service_rest.close(); } @@ -1860,31 +1858,31 @@ void t_php_generator::generate_service_client(t_service* tservice) { } f_service_client << "class " << php_namespace_declaration(tservice) << "Client" << extends_client - << " implements " << php_namespace(tservice->get_program()) << service_name_ << "If" << endl - <<"{"<< endl; + << " implements " << php_namespace(tservice->get_program()) << service_name_ << "If" << '\n' + <<"{"<< '\n'; indent_up(); // Private members if (extends.empty()) { - f_service_client << indent() << "protected $input_ = null;" << endl << indent() - << "protected $output_ = null;" << endl << endl; - f_service_client << indent() << "protected $seqid_ = 0;" << endl << endl; + f_service_client << indent() << "protected $input_ = null;" << '\n' << indent() + << "protected $output_ = null;" << '\n' << '\n'; + f_service_client << indent() << "protected $seqid_ = 0;" << '\n' << '\n'; } // Constructor function - f_service_client << indent() << "public function __construct($input, $output = null)" << endl - << indent() << "{" << endl; + f_service_client << indent() << "public function __construct($input, $output = null)" << '\n' + << indent() << "{" << '\n'; indent_up(); if (!extends.empty()) { - f_service_client << indent() << "parent::__construct($input, $output);" << endl; + f_service_client << indent() << "parent::__construct($input, $output);" << '\n'; } else { - f_service_client << indent() << "$this->input_ = $input;" << endl - << indent() << "$this->output_ = $output ? $output : $input;" << endl; + f_service_client << indent() << "$this->input_ = $input;" << '\n' + << indent() << "$this->output_ = $output ? $output : $input;" << '\n'; } indent_down(); - f_service_client << indent() << "}" << endl << endl; + f_service_client << indent() << "}" << '\n' << '\n'; // Generate client method implementations vector functions = tservice->get_functions(); @@ -1895,10 +1893,10 @@ void t_php_generator::generate_service_client(t_service* tservice) { vector::const_iterator fld_iter; string funname = (*f_iter)->get_name(); - f_service_client << endl; + f_service_client << '\n'; // Open function - indent(f_service_client) << "public function " << function_signature(*f_iter) << endl; + indent(f_service_client) << "public function " << function_signature(*f_iter) << '\n'; scope_up(f_service_client); indent(f_service_client) << "$this->send_" << funname << "("; @@ -1911,77 +1909,77 @@ void t_php_generator::generate_service_client(t_service* tservice) { } f_service_client << "$" << (*fld_iter)->get_name(); } - f_service_client << ");" << endl; + f_service_client << ");" << '\n'; if (!(*f_iter)->is_oneway()) { f_service_client << indent(); if (!(*f_iter)->get_returntype()->is_void()) { f_service_client << "return "; } - f_service_client << "$this->recv_" << funname << "();" << endl; + f_service_client << "$this->recv_" << funname << "();" << '\n'; } scope_down(f_service_client); - f_service_client << endl; + f_service_client << '\n'; - indent(f_service_client) << "public function send_" << function_signature(*f_iter) << endl; + indent(f_service_client) << "public function send_" << function_signature(*f_iter) << '\n'; scope_up(f_service_client); std::string argsname = php_namespace(tservice->get_program()) + service_name_ + "_" + (*f_iter)->get_name() + "_args"; - f_service_client << indent() << "$args = new " << argsname << "();" << endl; + f_service_client << indent() << "$args = new " << argsname << "();" << '\n'; for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) { f_service_client << indent() << "$args->" << (*fld_iter)->get_name() << " = $" - << (*fld_iter)->get_name() << ";" << endl; + << (*fld_iter)->get_name() << ";" << '\n'; } f_service_client << indent() << "$bin_accel = ($this->output_ instanceof " << "TBinaryProtocolAccelerated) && function_exists('thrift_protocol_write_binary');" - << endl; + << '\n'; - f_service_client << indent() << "if ($bin_accel) {" << endl; + f_service_client << indent() << "if ($bin_accel) {" << '\n'; indent_up(); string messageType = (*f_iter)->is_oneway() ? "TMessageType::ONEWAY" : "TMessageType::CALL"; - f_service_client << indent() << "thrift_protocol_write_binary(" << endl; + f_service_client << indent() << "thrift_protocol_write_binary(" << '\n'; indent_up(); - f_service_client << indent() << "$this->output_," << endl - << indent() << "'" << (*f_iter)->get_name() << "'," << endl - << indent() << messageType << "," << endl - << indent() << "$args," << endl - << indent() << "$this->seqid_," << endl - << indent() << "$this->output_->isStrictWrite()" << endl; + f_service_client << indent() << "$this->output_," << '\n' + << indent() << "'" << (*f_iter)->get_name() << "'," << '\n' + << indent() << messageType << "," << '\n' + << indent() << "$args," << '\n' + << indent() << "$this->seqid_," << '\n' + << indent() << "$this->output_->isStrictWrite()" << '\n'; indent_down(); - f_service_client << indent() << ");" << endl; + f_service_client << indent() << ");" << '\n'; indent_down(); - f_service_client << indent() << "} else {" << endl; + f_service_client << indent() << "} else {" << '\n'; indent_up(); // Serialize the request header if (binary_inline_) { - f_service_client << indent() << "$buff = pack('N', (0x80010000 | " << messageType << "));" << endl - << indent() << "$buff .= pack('N', strlen('" << funname << "'));" << endl - << indent() << "$buff .= '" << funname << "';" << endl << indent() - << "$buff .= pack('N', $this->seqid_);" << endl; + f_service_client << indent() << "$buff = pack('N', (0x80010000 | " << messageType << "));" << '\n' + << indent() << "$buff .= pack('N', strlen('" << funname << "'));" << '\n' + << indent() << "$buff .= '" << funname << "';" << '\n' << indent() + << "$buff .= pack('N', $this->seqid_);" << '\n'; } else { f_service_client << indent() << "$this->output_->writeMessageBegin('" << (*f_iter)->get_name() - << "', " << messageType << ", $this->seqid_);" << endl; + << "', " << messageType << ", $this->seqid_);" << '\n'; } // Write to the stream if (binary_inline_) { - f_service_client << indent() << "$args->write($buff);" << endl << indent() - << "$this->output_->write($buff);" << endl << indent() - << "$this->output_->flush();" << endl; + f_service_client << indent() << "$args->write($buff);" << '\n' << indent() + << "$this->output_->write($buff);" << '\n' << indent() + << "$this->output_->flush();" << '\n'; } else { - f_service_client << indent() << "$args->write($this->output_);" << endl << indent() - << "$this->output_->writeMessageEnd();" << endl << indent() - << "$this->output_->getTransport()->flush();" << endl; + f_service_client << indent() << "$args->write($this->output_);" << '\n' << indent() + << "$this->output_->writeMessageEnd();" << '\n' << indent() + << "$this->output_->getTransport()->flush();" << '\n'; } scope_down(f_service_client); @@ -1997,98 +1995,98 @@ void t_php_generator::generate_service_client(t_service* tservice) { string("recv_") + (*f_iter)->get_name(), &noargs); // Open function - f_service_client << endl << indent() << "public function " << function_signature(&recv_function) - << endl; + f_service_client << '\n' << indent() << "public function " << function_signature(&recv_function) + << '\n'; scope_up(f_service_client); f_service_client << indent() << "$bin_accel = ($this->input_ instanceof " << "TBinaryProtocolAccelerated)" - << " && function_exists('thrift_protocol_read_binary');" << endl; + << " && function_exists('thrift_protocol_read_binary');" << '\n'; - f_service_client << indent() << "if ($bin_accel) {" << endl; + f_service_client << indent() << "if ($bin_accel) {" << '\n'; indent_up(); - f_service_client << indent() << "$result = thrift_protocol_read_binary(" << endl; + f_service_client << indent() << "$result = thrift_protocol_read_binary(" << '\n'; indent_up(); - f_service_client << indent() << "$this->input_," << endl - << indent() << "'" << resultname << "'," << endl - << indent() << "$this->input_->isStrictRead()" << endl; + f_service_client << indent() << "$this->input_," << '\n' + << indent() << "'" << resultname << "'," << '\n' + << indent() << "$this->input_->isStrictRead()" << '\n'; indent_down(); - f_service_client << indent() << ");" << endl; + f_service_client << indent() << ");" << '\n'; indent_down(); - f_service_client << indent() << "} else {" << endl; + f_service_client << indent() << "} else {" << '\n'; indent_up(); - f_service_client << indent() << "$rseqid = 0;" << endl - << indent() << "$fname = null;" << endl - << indent() << "$mtype = 0;" << endl << endl; + f_service_client << indent() << "$rseqid = 0;" << '\n' + << indent() << "$fname = null;" << '\n' + << indent() << "$mtype = 0;" << '\n' << '\n'; if (binary_inline_) { t_field ffname(g_type_string, "fname"); t_field fseqid(g_type_i32, "rseqid"); - f_service_client << indent() << "$ver = unpack('N', $this->input_->readAll(4));" << endl - << indent() << "$ver = $ver[1];" << endl << indent() << "$mtype = $ver & 0xff;" - << endl << indent() << "$ver = $ver & 0xffff0000;" << endl << indent() + f_service_client << indent() << "$ver = unpack('N', $this->input_->readAll(4));" << '\n' + << indent() << "$ver = $ver[1];" << '\n' << indent() << "$mtype = $ver & 0xff;" + << '\n' << indent() << "$ver = $ver & 0xffff0000;" << '\n' << indent() << "if ($ver != 0x80010000) throw new " << "TProtocolException('Bad version identifier: '.$ver, " - << "TProtocolException::BAD_VERSION);" << endl; + << "TProtocolException::BAD_VERSION);" << '\n'; generate_deserialize_field(f_service_client, &ffname, "", true); generate_deserialize_field(f_service_client, &fseqid, "", true); } else { - f_service_client << indent() << "$this->input_->readMessageBegin($fname, $mtype, $rseqid);" << endl - << indent() << "if ($mtype == TMessageType::EXCEPTION) {" << endl; + f_service_client << indent() << "$this->input_->readMessageBegin($fname, $mtype, $rseqid);" << '\n' + << indent() << "if ($mtype == TMessageType::EXCEPTION) {" << '\n'; indent_up(); - f_service_client << indent() << "$x = new TApplicationException();" << endl - << indent() << "$x->read($this->input_);" << endl - << indent() << "$this->input_->readMessageEnd();" << endl - << indent() << "throw $x;" << endl; + f_service_client << indent() << "$x = new TApplicationException();" << '\n' + << indent() << "$x->read($this->input_);" << '\n' + << indent() << "$this->input_->readMessageEnd();" << '\n' + << indent() << "throw $x;" << '\n'; indent_down(); - f_service_client << indent() << "}" << endl; + f_service_client << indent() << "}" << '\n'; } - f_service_client << indent() << "$result = new " << resultname << "();" << endl - << indent() << "$result->read($this->input_);" << endl; + f_service_client << indent() << "$result = new " << resultname << "();" << '\n' + << indent() << "$result->read($this->input_);" << '\n'; if (!binary_inline_) { - f_service_client << indent() << "$this->input_->readMessageEnd();" << endl; + f_service_client << indent() << "$this->input_->readMessageEnd();" << '\n'; } scope_down(f_service_client); // Careful, only return result if not a void function if (!(*f_iter)->get_returntype()->is_void()) { - f_service_client << indent() << "if ($result->success !== null) {" << endl; + f_service_client << indent() << "if ($result->success !== null) {" << '\n'; indent_up(); - f_service_client << indent() << "return $result->success;" << endl; + f_service_client << indent() << "return $result->success;" << '\n'; indent_down(); - f_service_client << indent() << "}" << endl; + f_service_client << indent() << "}" << '\n'; } t_struct* xs = (*f_iter)->get_xceptions(); const std::vector& xceptions = xs->get_members(); vector::const_iterator x_iter; for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { - f_service_client << indent() << "if ($result->" << (*x_iter)->get_name() << " !== null) {" << endl; + f_service_client << indent() << "if ($result->" << (*x_iter)->get_name() << " !== null) {" << '\n'; indent_up(); - f_service_client << indent() << "throw $result->" << (*x_iter)->get_name() << ";" << endl; + f_service_client << indent() << "throw $result->" << (*x_iter)->get_name() << ";" << '\n'; indent_down(); - f_service_client << indent() << "}" << endl; + f_service_client << indent() << "}" << '\n'; } // Careful, only return _result if not a void function if ((*f_iter)->get_returntype()->is_void()) { - indent(f_service_client) << "return;" << endl; + indent(f_service_client) << "return;" << '\n'; } else { f_service_client << indent() << "throw new \\Exception(\"" << (*f_iter)->get_name() - << " failed: unknown result\");" << endl; + << " failed: unknown result\");" << '\n'; } // Close function @@ -2097,7 +2095,7 @@ void t_php_generator::generate_service_client(t_service* tservice) { } indent_down(); - f_service_client << "}" << endl; + f_service_client << "}" << '\n'; // Close service client file if (!classmap_) { @@ -2138,54 +2136,54 @@ void t_php_generator::generate_deserialize_field(ostream& out, throw "compiler error: cannot serialize void field in a struct: " + name; break; case t_base_type::TYPE_STRING: - out << indent() << "$len = unpack('N', " << itrans << "->readAll(4));" << endl - << indent() << "$len = $len[1];" << endl << indent() << "if ($len > 0x7fffffff) {" - << endl << indent() << " $len = 0 - (($len - 1) ^ 0xffffffff);" << endl << indent() - << "}" << endl << indent() << "$" << name << " = " << itrans << "->readAll($len);" - << endl; + out << indent() << "$len = unpack('N', " << itrans << "->readAll(4));" << '\n' + << indent() << "$len = $len[1];" << '\n' << indent() << "if ($len > 0x7fffffff) {" + << '\n' << indent() << " $len = 0 - (($len - 1) ^ 0xffffffff);" << '\n' << indent() + << "}" << '\n' << indent() << "$" << name << " = " << itrans << "->readAll($len);" + << '\n'; break; case t_base_type::TYPE_BOOL: out << indent() << "$" << name << " = unpack('c', " << itrans << "->readAll(1));" - << endl << indent() << "$" << name << " = (bool)$" << name << "[1];" << endl; + << '\n' << indent() << "$" << name << " = (bool)$" << name << "[1];" << '\n'; break; case t_base_type::TYPE_I8: out << indent() << "$" << name << " = unpack('c', " << itrans << "->readAll(1));" - << endl << indent() << "$" << name << " = $" << name << "[1];" << endl; + << '\n' << indent() << "$" << name << " = $" << name << "[1];" << '\n'; break; case t_base_type::TYPE_I16: - out << indent() << "$val = unpack('n', " << itrans << "->readAll(2));" << endl - << indent() << "$val = $val[1];" << endl << indent() << "if ($val > 0x7fff) {" - << endl << indent() << " $val = 0 - (($val - 1) ^ 0xffff);" << endl << indent() - << "}" << endl << indent() << "$" << name << " = $val;" << endl; + out << indent() << "$val = unpack('n', " << itrans << "->readAll(2));" << '\n' + << indent() << "$val = $val[1];" << '\n' << indent() << "if ($val > 0x7fff) {" + << '\n' << indent() << " $val = 0 - (($val - 1) ^ 0xffff);" << '\n' << indent() + << "}" << '\n' << indent() << "$" << name << " = $val;" << '\n'; break; case t_base_type::TYPE_I32: - out << indent() << "$val = unpack('N', " << itrans << "->readAll(4));" << endl - << indent() << "$val = $val[1];" << endl << indent() << "if ($val > 0x7fffffff) {" - << endl << indent() << " $val = 0 - (($val - 1) ^ 0xffffffff);" << endl << indent() - << "}" << endl << indent() << "$" << name << " = $val;" << endl; + out << indent() << "$val = unpack('N', " << itrans << "->readAll(4));" << '\n' + << indent() << "$val = $val[1];" << '\n' << indent() << "if ($val > 0x7fffffff) {" + << '\n' << indent() << " $val = 0 - (($val - 1) ^ 0xffffffff);" << '\n' << indent() + << "}" << '\n' << indent() << "$" << name << " = $val;" << '\n'; break; case t_base_type::TYPE_I64: - out << indent() << "$arr = unpack('N2', " << itrans << "->readAll(8));" << endl - << indent() << "if ($arr[1] & 0x80000000) {" << endl << indent() - << " $arr[1] = $arr[1] ^ 0xFFFFFFFF;" << endl << indent() - << " $arr[2] = $arr[2] ^ 0xFFFFFFFF;" << endl << indent() << " $" << name - << " = 0 - $arr[1]*4294967296 - $arr[2] - 1;" << endl << indent() << "} else {" - << endl << indent() << " $" << name << " = $arr[1]*4294967296 + $arr[2];" << endl - << indent() << "}" << endl; + out << indent() << "$arr = unpack('N2', " << itrans << "->readAll(8));" << '\n' + << indent() << "if ($arr[1] & 0x80000000) {" << '\n' << indent() + << " $arr[1] = $arr[1] ^ 0xFFFFFFFF;" << '\n' << indent() + << " $arr[2] = $arr[2] ^ 0xFFFFFFFF;" << '\n' << indent() << " $" << name + << " = 0 - $arr[1]*4294967296 - $arr[2] - 1;" << '\n' << indent() << "} else {" + << '\n' << indent() << " $" << name << " = $arr[1]*4294967296 + $arr[2];" << '\n' + << indent() << "}" << '\n'; break; case t_base_type::TYPE_DOUBLE: - out << indent() << "$arr = unpack('d', strrev(" << itrans << "->readAll(8)));" << endl - << indent() << "$" << name << " = $arr[1];" << endl; + out << indent() << "$arr = unpack('d', strrev(" << itrans << "->readAll(8)));" << '\n' + << indent() << "$" << name << " = $arr[1];" << '\n'; break; default: throw "compiler error: no PHP name for base type " + t_base_type::t_base_name(tbase) + tfield->get_name(); } } else if (type->is_enum()) { - out << indent() << "$val = unpack('N', " << itrans << "->readAll(4));" << endl << indent() - << "$val = $val[1];" << endl << indent() << "if ($val > 0x7fffffff) {" << endl - << indent() << " $val = 0 - (($val - 1) ^ 0xffffffff);" << endl << indent() << "}" - << endl << indent() << "$" << name << " = $val;" << endl; + out << indent() << "$val = unpack('N', " << itrans << "->readAll(4));" << '\n' << indent() + << "$val = $val[1];" << '\n' << indent() << "if ($val > 0x7fffffff) {" << '\n' + << indent() << " $val = 0 - (($val - 1) ^ 0xffffffff);" << '\n' << indent() << "}" + << '\n' << indent() << "$" << name << " = $val;" << '\n'; } } else { @@ -2224,7 +2222,7 @@ void t_php_generator::generate_deserialize_field(ostream& out, } else if (type->is_enum()) { out << "readI32($" << name << ");"; } - out << endl; + out << '\n'; } } else { printf("DO NOT KNOW HOW TO DESERIALIZE FIELD '%s' TYPE '%s'\n", @@ -2242,8 +2240,8 @@ void t_php_generator::generate_deserialize_field(ostream& out, */ void t_php_generator::generate_deserialize_struct(ostream& out, t_struct* tstruct, string prefix) { out << indent() << "$" << prefix << " = new " << php_namespace(tstruct->get_program()) - << tstruct->get_name() << "();" << endl << indent() << "$xfer += $" << prefix - << "->read($input);" << endl; + << tstruct->get_name() << "();" << '\n' << indent() << "$xfer += $" << prefix + << "->read($input);" << '\n'; } void t_php_generator::generate_deserialize_container(ostream& out, t_type* ttype, string prefix) { @@ -2257,44 +2255,44 @@ void t_php_generator::generate_deserialize_container(ostream& out, t_type* ttype t_field fvtype(g_type_i8, vtype); t_field fetype(g_type_i8, etype); - out << indent() << "$" << prefix << " = array();" << endl << indent() << "$" << size << " = 0;" - << endl; + out << indent() << "$" << prefix << " = array();" << '\n' << indent() << "$" << size << " = 0;" + << '\n'; // Declare variables, read header if (ttype->is_map()) { - out << indent() << "$" << ktype << " = 0;" << endl << indent() << "$" << vtype << " = 0;" - << endl; + out << indent() << "$" << ktype << " = 0;" << '\n' << indent() << "$" << vtype << " = 0;" + << '\n'; if (binary_inline_) { generate_deserialize_field(out, &fktype); generate_deserialize_field(out, &fvtype); generate_deserialize_field(out, &fsize); } else { out << indent() << "$xfer += $input->readMapBegin(" - << "$" << ktype << ", $" << vtype << ", $" << size << ");" << endl; + << "$" << ktype << ", $" << vtype << ", $" << size << ");" << '\n'; } } else if (ttype->is_set()) { if (binary_inline_) { generate_deserialize_field(out, &fetype); generate_deserialize_field(out, &fsize); } else { - out << indent() << "$" << etype << " = 0;" << endl << indent() + out << indent() << "$" << etype << " = 0;" << '\n' << indent() << "$xfer += $input->readSetBegin(" - << "$" << etype << ", $" << size << ");" << endl; + << "$" << etype << ", $" << size << ");" << '\n'; } } else if (ttype->is_list()) { if (binary_inline_) { generate_deserialize_field(out, &fetype); generate_deserialize_field(out, &fsize); } else { - out << indent() << "$" << etype << " = 0;" << endl << indent() + out << indent() << "$" << etype << " = 0;" << '\n' << indent() << "$xfer += $input->readListBegin(" - << "$" << etype << ", $" << size << ");" << endl; + << "$" << etype << ", $" << size << ");" << '\n'; } } // For loop iterates over elements string i = tmp("_i"); - indent(out) << "for ($" << i << " = 0; $" << i << " < $" << size << "; ++$" << i << ") {" << endl; + indent(out) << "for ($" << i << " = 0; $" << i << " < $" << size << "; ++$" << i << ") {" << '\n'; indent_up(); @@ -2311,11 +2309,11 @@ void t_php_generator::generate_deserialize_container(ostream& out, t_type* ttype if (!binary_inline_) { // Read container end if (ttype->is_map()) { - indent(out) << "$xfer += $input->readMapEnd();" << endl; + indent(out) << "$xfer += $input->readMapEnd();" << '\n'; } else if (ttype->is_set()) { - indent(out) << "$xfer += $input->readSetEnd();" << endl; + indent(out) << "$xfer += $input->readSetEnd();" << '\n'; } else if (ttype->is_list()) { - indent(out) << "$xfer += $input->readListEnd();" << endl; + indent(out) << "$xfer += $input->readListEnd();" << '\n'; } } } @@ -2329,28 +2327,28 @@ void t_php_generator::generate_deserialize_map_element(ostream& out, t_map* tmap t_field fkey(tmap->get_key_type(), key); t_field fval(tmap->get_val_type(), val); - indent(out) << declare_field(&fkey, true, true) << endl; - indent(out) << declare_field(&fval, true, true) << endl; + indent(out) << declare_field(&fkey, true, true) << '\n'; + indent(out) << declare_field(&fval, true, true) << '\n'; generate_deserialize_field(out, &fkey); generate_deserialize_field(out, &fval); - indent(out) << "$" << prefix << "[$" << key << "] = $" << val << ";" << endl; + indent(out) << "$" << prefix << "[$" << key << "] = $" << val << ";" << '\n'; } void t_php_generator::generate_deserialize_set_element(ostream& out, t_set* tset, string prefix) { string elem = tmp("elem"); t_field felem(tset->get_elem_type(), elem); - indent(out) << "$" << elem << " = null;" << endl; + indent(out) << "$" << elem << " = null;" << '\n'; generate_deserialize_field(out, &felem); t_type* elem_type = tset->get_elem_type(); if(php_is_scalar(elem_type)) { - indent(out) << "$" << prefix << "[$" << elem << "] = true;" << endl; + indent(out) << "$" << prefix << "[$" << elem << "] = true;" << '\n'; } else { - indent(out) << "$" << prefix << "[] = $" << elem << ";" << endl; + indent(out) << "$" << prefix << "[] = $" << elem << ";" << '\n'; } } @@ -2360,11 +2358,11 @@ void t_php_generator::generate_deserialize_list_element(ostream& out, string elem = tmp("elem"); t_field felem(tlist->get_elem_type(), elem); - indent(out) << "$" << elem << " = null;" << endl; + indent(out) << "$" << elem << " = null;" << '\n'; generate_deserialize_field(out, &felem); - indent(out) << "$" << prefix << " []= $" << elem << ";" << endl; + indent(out) << "$" << prefix << " []= $" << elem << ";" << '\n'; } /** @@ -2397,33 +2395,33 @@ void t_php_generator::generate_serialize_field(ostream& out, t_field* tfield, st throw "compiler error: cannot serialize void field in a struct: " + name; break; case t_base_type::TYPE_STRING: - out << indent() << "$output .= pack('N', strlen($" << name << "));" << endl << indent() - << "$output .= $" << name << ";" << endl; + out << indent() << "$output .= pack('N', strlen($" << name << "));" << '\n' << indent() + << "$output .= $" << name << ";" << '\n'; break; case t_base_type::TYPE_BOOL: - out << indent() << "$output .= pack('c', $" << name << " ? 1 : 0);" << endl; + out << indent() << "$output .= pack('c', $" << name << " ? 1 : 0);" << '\n'; break; case t_base_type::TYPE_I8: - out << indent() << "$output .= pack('c', $" << name << ");" << endl; + out << indent() << "$output .= pack('c', $" << name << ");" << '\n'; break; case t_base_type::TYPE_I16: - out << indent() << "$output .= pack('n', $" << name << ");" << endl; + out << indent() << "$output .= pack('n', $" << name << ");" << '\n'; break; case t_base_type::TYPE_I32: - out << indent() << "$output .= pack('N', $" << name << ");" << endl; + out << indent() << "$output .= pack('N', $" << name << ");" << '\n'; break; case t_base_type::TYPE_I64: out << indent() << "$output .= pack('N2', $" << name << " >> 32, $" << name - << " & 0xFFFFFFFF);" << endl; + << " & 0xFFFFFFFF);" << '\n'; break; case t_base_type::TYPE_DOUBLE: - out << indent() << "$output .= strrev(pack('d', $" << name << "));" << endl; + out << indent() << "$output .= strrev(pack('d', $" << name << "));" << '\n'; break; default: throw "compiler error: no PHP name for base type " + t_base_type::t_base_name(tbase); } } else if (type->is_enum()) { - out << indent() << "$output .= pack('N', $" << name << ");" << endl; + out << indent() << "$output .= pack('N', $" << name << ");" << '\n'; } } else { @@ -2462,7 +2460,7 @@ void t_php_generator::generate_serialize_field(ostream& out, t_field* tfield, st } else if (type->is_enum()) { out << "writeI32($" << name << ");"; } - out << endl; + out << '\n'; } } else { printf("DO NOT KNOW HOW TO SERIALIZE FIELD '%s%s' TYPE '%s'\n", @@ -2480,7 +2478,7 @@ void t_php_generator::generate_serialize_field(ostream& out, t_field* tfield, st */ void t_php_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix) { (void)tstruct; - indent(out) << "$xfer += $" << prefix << "->write($output);" << endl; + indent(out) << "$xfer += $" << prefix << "->write($output);" << '\n'; } /** @@ -2490,35 +2488,35 @@ void t_php_generator::generate_serialize_container(ostream& out, t_type* ttype, if (ttype->is_map()) { if (binary_inline_) { out << indent() << "$output .= pack('c', " << type_to_enum(((t_map*)ttype)->get_key_type()) - << ");" << endl << indent() << "$output .= pack('c', " - << type_to_enum(((t_map*)ttype)->get_val_type()) << ");" << endl << indent() - << "$output .= strrev(pack('l', count($" << prefix << ")));" << endl; + << ");" << '\n' << indent() << "$output .= pack('c', " + << type_to_enum(((t_map*)ttype)->get_val_type()) << ");" << '\n' << indent() + << "$output .= strrev(pack('l', count($" << prefix << ")));" << '\n'; } else { indent(out) << "$output->writeMapBegin(" << type_to_enum(((t_map*)ttype)->get_key_type()) << ", " << type_to_enum(((t_map*)ttype)->get_val_type()) << ", " - << "count($" << prefix << "));" << endl; + << "count($" << prefix << "));" << '\n'; } } else if (ttype->is_set()) { if (binary_inline_) { out << indent() << "$output .= pack('c', " << type_to_enum(((t_set*)ttype)->get_elem_type()) - << ");" << endl << indent() << "$output .= strrev(pack('l', count($" << prefix << ")));" - << endl; + << ");" << '\n' << indent() << "$output .= strrev(pack('l', count($" << prefix << ")));" + << '\n'; } else { indent(out) << "$output->writeSetBegin(" << type_to_enum(((t_set*)ttype)->get_elem_type()) << ", " - << "count($" << prefix << "));" << endl; + << "count($" << prefix << "));" << '\n'; } } else if (ttype->is_list()) { if (binary_inline_) { out << indent() << "$output .= pack('c', " << type_to_enum(((t_list*)ttype)->get_elem_type()) - << ");" << endl << indent() << "$output .= strrev(pack('l', count($" << prefix << ")));" - << endl; + << ");" << '\n' << indent() << "$output .= strrev(pack('l', count($" << prefix << ")));" + << '\n'; } else { indent(out) << "$output->writeListBegin(" << type_to_enum(((t_list*)ttype)->get_elem_type()) << ", " - << "count($" << prefix << "));" << endl; + << "count($" << prefix << "));" << '\n'; } } @@ -2526,14 +2524,14 @@ void t_php_generator::generate_serialize_container(ostream& out, t_type* ttype, string kiter = tmp("kiter"); string viter = tmp("viter"); indent(out) << "foreach ($" << prefix << " as " - << "$" << kiter << " => $" << viter << ") {" << endl; + << "$" << kiter << " => $" << viter << ") {" << '\n'; indent_up(); generate_serialize_map_element(out, (t_map*)ttype, kiter, viter); scope_down(out); } else if (ttype->is_set()) { string iter = tmp("iter"); string iter_val = tmp("iter"); - indent(out) << "foreach ($" << prefix << " as $" << iter << " => $" << iter_val << ") {" << endl; + indent(out) << "foreach ($" << prefix << " as $" << iter << " => $" << iter_val << ") {" << '\n'; indent_up(); t_type* elem_type = ((t_set*)ttype)->get_elem_type(); @@ -2545,7 +2543,7 @@ void t_php_generator::generate_serialize_container(ostream& out, t_type* ttype, scope_down(out); } else if (ttype->is_list()) { string iter = tmp("iter"); - indent(out) << "foreach ($" << prefix << " as $" << iter << ") {" << endl; + indent(out) << "foreach ($" << prefix << " as $" << iter << ") {" << '\n'; indent_up(); generate_serialize_list_element(out, (t_list*)ttype, iter); scope_down(out); @@ -2553,11 +2551,11 @@ void t_php_generator::generate_serialize_container(ostream& out, t_type* ttype, if (!binary_inline_) { if (ttype->is_map()) { - indent(out) << "$output->writeMapEnd();" << endl; + indent(out) << "$output->writeMapEnd();" << '\n'; } else if (ttype->is_set()) { - indent(out) << "$output->writeSetEnd();" << endl; + indent(out) << "$output->writeSetEnd();" << '\n'; } else if (ttype->is_list()) { - indent(out) << "$output->writeListEnd();" << endl; + indent(out) << "$output->writeListEnd();" << '\n'; } } } @@ -2617,12 +2615,12 @@ void t_php_generator::generate_php_doc(ostream& out, t_field* field) { // prepend free-style doc if available if (field->has_doc()) { - ss << field->get_doc() << endl; + ss << field->get_doc() << '\n'; } // append @var tag t_type* type = get_true_type(field->get_type()); - ss << "@var " << type_to_phpdoc(type) << endl; + ss << "@var " << type_to_phpdoc(type) << '\n'; generate_php_docstring_comment(out, ss.str()); } @@ -2633,7 +2631,7 @@ void t_php_generator::generate_php_doc(ostream& out, t_field* field) { void t_php_generator::generate_php_doc(ostream& out, t_function* function) { stringstream ss; if (function->has_doc()) { - ss << function->get_doc() << endl; + ss << function->get_doc() << '\n'; } // generate parameter types doc @@ -2645,7 +2643,7 @@ void t_php_generator::generate_php_doc(ostream& out, t_function* function) { if (arg->has_doc()) { ss << " " << arg->get_doc(); } - ss << endl; + ss << '\n'; } // generate return type doc @@ -2655,7 +2653,7 @@ void t_php_generator::generate_php_doc(ostream& out, t_function* function) { if (ret_type->has_doc()) { ss << " " << ret_type->get_doc(); } - ss << endl; + ss << '\n'; } // generate exceptions doc @@ -2667,7 +2665,7 @@ void t_php_generator::generate_php_doc(ostream& out, t_function* function) { if (exc->has_doc()) { ss << " " << exc->get_doc(); } - ss << endl; + ss << '\n'; } generate_docstring_comment(out, "/**\n", " * ", ss.str(), " */\n"); diff --git a/compiler/cpp/src/thrift/generate/t_py_generator.cc b/compiler/cpp/src/thrift/generate/t_py_generator.cc index ffabd56521f..c34bb43bcbd 100644 --- a/compiler/cpp/src/thrift/generate/t_py_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_py_generator.cc @@ -40,8 +40,6 @@ using std::string; using std::stringstream; using std::vector; -static const string endl = "\n"; // avoid ostream << std::endl flushes - /** * Python code generator. * @@ -65,6 +63,7 @@ class t_py_generator : public t_generator { gen_twisted_ = false; gen_dynamic_ = false; gen_enum_ = false; + gen_type_hints_ = false; coding_ = ""; gen_dynbaseclass_ = ""; gen_dynbaseclass_exc_ = ""; @@ -127,6 +126,11 @@ class t_py_generator : public t_generator { gen_tornado_ = true; } else if( iter->first.compare("coding") == 0) { coding_ = iter->second; + } else if (iter->first.compare("type_hints") == 0) { + if (!gen_enum_) { + throw "the type_hints py option requires the enum py option"; + } + gen_type_hints_ = true; } else { throw "unknown option py:" + iter->first; } @@ -254,12 +258,16 @@ class t_py_generator : public t_generator { std::string declare_argument(t_field* tfield); std::string render_field_default_value(t_field* tfield); std::string type_name(t_type* ttype); - std::string function_signature(t_function* tfunction, bool interface = false); + std::string function_signature(t_function* tfunction, bool interface = false, bool send_part = false); std::string argument_list(t_struct* tstruct, std::vector* pre = nullptr, std::vector* post = nullptr); std::string type_to_enum(t_type* ttype); std::string type_to_spec_args(t_type* ttype); + std::string type_to_py_type(t_type* type); + std::string member_hint(t_type* type, t_field::e_req req); + std::string arg_hint(t_type* type); + std::string func_hint(t_type* type); static bool is_valid_namespace(const std::string& sub_namespace) { return sub_namespace == "twisted"; @@ -316,6 +324,11 @@ class t_py_generator : public t_generator { bool gen_slots_; + /** + * True if we should generate classes type hints and type checks in write methods. + */ + bool gen_type_hints_; + std::string copy_options_; /** @@ -414,22 +427,22 @@ void t_py_generator::init_generator() { for (sv_iter = services.begin(); sv_iter != services.end(); ++sv_iter) { f_init << ", '" << (*sv_iter)->get_name() << "'"; } - f_init << "]" << endl; + f_init << "]" << '\n'; f_init.close(); // Print header - f_types_ << py_autogen_comment() << endl - << py_imports() << endl - << render_includes() << endl - << "from thrift.transport import TTransport" << endl + f_types_ << py_autogen_comment() << '\n' + << py_imports() << '\n' + << render_includes() << '\n' + << "from thrift.transport import TTransport" << '\n' << import_dynbase_; - f_types_ << "all_structs = []" << endl; + f_types_ << "all_structs = []" << '\n'; f_consts_ << - py_autogen_comment() << endl << - py_imports() << endl << - "from .ttypes import *" << endl; + py_autogen_comment() << '\n' << + py_imports() << '\n' << + "from .ttypes import *" << '\n'; } /** @@ -462,18 +475,24 @@ string t_py_generator::py_autogen_comment() { */ string t_py_generator::py_imports() { ostringstream ss; + if (gen_type_hints_) { + ss << "from __future__ import annotations" << '\n' << "import typing" << '\n'; + } + ss << "from thrift.Thrift import TType, TMessageType, TFrozenDict, TException, " "TApplicationException" - << endl + << '\n' << "from thrift.protocol.TProtocol import TProtocolException" - << endl + << '\n' << "from thrift.TRecursive import fix_spec" - << endl; + << '\n' + << "from uuid import UUID" + << '\n'; if (gen_enum_) { - ss << "from enum import IntEnum" << endl; + ss << "from enum import IntEnum" << '\n'; } if (gen_utf8strings_) { - ss << endl << "import sys"; + ss << '\n' << "import sys"; } return ss.str(); } @@ -484,8 +503,8 @@ string t_py_generator::py_imports() { void t_py_generator::close_generator() { // Fix thrift_spec definitions for recursive structs. - f_types_ << "fix_spec(all_structs)" << endl; - f_types_ << "del all_structs" << endl; + f_types_ << "fix_spec(all_structs)" << '\n'; + f_types_ << "del all_structs" << '\n'; // Close types file f_types_.close(); @@ -519,37 +538,37 @@ void t_py_generator::generate_enum(t_enum* tenum) { base_class = gen_dynbaseclass_; } - f_types_ << endl - << endl + f_types_ << '\n' + << '\n' << "class " << tenum->get_name() << (base_class.empty() ? "" : "(" + base_class + ")") << ":" - << endl; + << '\n'; indent_up(); generate_python_docstring(f_types_, tenum); - to_string_mapping << indent() << "_VALUES_TO_NAMES = {" << endl; - from_string_mapping << indent() << "_NAMES_TO_VALUES = {" << endl; + to_string_mapping << indent() << "_VALUES_TO_NAMES = {" << '\n'; + from_string_mapping << indent() << "_NAMES_TO_VALUES = {" << '\n'; vector constants = tenum->get_constants(); vector::iterator c_iter; for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) { int value = (*c_iter)->get_value(); - indent(f_types_) << (*c_iter)->get_name() << " = " << value << endl; + indent(f_types_) << (*c_iter)->get_name() << " = " << value << '\n'; // Dictionaries to/from string names of enums to_string_mapping << indent() << indent() << value << ": \"" - << escape_string((*c_iter)->get_name()) << "\"," << endl; + << escape_string((*c_iter)->get_name()) << "\"," << '\n'; from_string_mapping << indent() << indent() << '"' << escape_string((*c_iter)->get_name()) - << "\": " << value << ',' << endl; + << "\": " << value << ',' << '\n'; } - to_string_mapping << indent() << "}" << endl; - from_string_mapping << indent() << "}" << endl; + to_string_mapping << indent() << "}" << '\n'; + from_string_mapping << indent() << "}" << '\n'; indent_down(); - f_types_ << endl; + f_types_ << '\n'; if (!gen_enum_) { - f_types_ << to_string_mapping.str() << endl << from_string_mapping.str(); + f_types_ << to_string_mapping.str() << '\n' << from_string_mapping.str(); } } @@ -562,7 +581,7 @@ void t_py_generator::generate_const(t_const* tconst) { t_const_value* value = tconst->get_value(); indent(f_consts_) << name << " = " << render_const_value(type, value); - f_consts_ << endl; + f_consts_ << '\n'; } /** @@ -599,6 +618,9 @@ string t_py_generator::render_const_value(t_type* type, t_const_value* value) { out << emit_double_as_string(value->get_double()); } break; + case t_base_type::TYPE_UUID: + out << "UUID(\"" << get_escaped_string(value) << "\")"; + break; default: throw "compiler error: no const of base type " + t_base_type::t_base_name(tbase); } @@ -612,7 +634,7 @@ string t_py_generator::render_const_value(t_type* type, t_const_value* value) { out << int_val; } } else if (type->is_struct() || type->is_xception()) { - out << type_name(type) << "(**{" << endl; + out << type_name(type) << "(**{" << '\n'; indent_up(); const vector& fields = ((t_struct*)type)->get_members(); vector::const_iterator f_iter; @@ -629,7 +651,7 @@ string t_py_generator::render_const_value(t_type* type, t_const_value* value) { throw "type error: " + type->get_name() + " has no field " + v_iter->first->get_string(); } indent(out) << render_const_value(g_type_string, v_iter->first) << ": " - << render_const_value(field_type, v_iter->second) << "," << endl; + << render_const_value(field_type, v_iter->second) << "," << '\n'; } indent_down(); indent(out) << "})"; @@ -639,13 +661,13 @@ string t_py_generator::render_const_value(t_type* type, t_const_value* value) { if (is_immutable(type)) { out << "TFrozenDict("; } - out << "{" << endl; + out << "{" << '\n'; indent_up(); const map& val = value->get_map(); map::const_iterator v_iter; for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { indent(out) << render_const_value(ktype, v_iter->first) << ": " - << render_const_value(vtype, v_iter->second) << "," << endl; + << render_const_value(vtype, v_iter->second) << "," << '\n'; } indent_down(); indent(out) << "}"; @@ -666,15 +688,15 @@ string t_py_generator::render_const_value(t_type* type, t_const_value* value) { out << "set("; } if (is_immutable(type) || type->is_set()) { - out << "(" << endl; + out << "(" << '\n'; } else { - out << "[" << endl; + out << "[" << '\n'; } indent_up(); const vector& val = value->get_list(); vector::const_iterator v_iter; for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { - indent(out) << render_const_value(etype, *v_iter) << "," << endl; + indent(out) << render_const_value(etype, *v_iter) << "," << '\n'; } indent_down(); if (is_immutable(type) || type->is_set()) { @@ -743,17 +765,17 @@ void t_py_generator::generate_py_thrift_spec(ostream& out, vector::const_iterator m_iter; // Add struct definition to list so thrift_spec can be fixed for recursive structures. - indent(out) << "all_structs.append(" << tstruct->get_name() << ")" << endl; + indent(out) << "all_structs.append(" << tstruct->get_name() << ")" << '\n'; if (sorted_members.empty() || (sorted_members[0]->get_key() >= 0)) { - indent(out) << tstruct->get_name() << ".thrift_spec = (" << endl; + indent(out) << tstruct->get_name() << ".thrift_spec = (" << '\n'; indent_up(); int sorted_keys_pos = 0; for (m_iter = sorted_members.begin(); m_iter != sorted_members.end(); ++m_iter) { for (; sorted_keys_pos != (*m_iter)->get_key(); sorted_keys_pos++) { - indent(out) << "None, # " << sorted_keys_pos << endl; + indent(out) << "None, # " << sorted_keys_pos << '\n'; } indent(out) << "(" << (*m_iter)->get_key() << ", " << type_to_enum((*m_iter)->get_type()) @@ -762,15 +784,15 @@ void t_py_generator::generate_py_thrift_spec(ostream& out, << ", " << type_to_spec_args((*m_iter)->get_type()) << ", " << render_field_default_value(*m_iter) << ", " << ")," - << " # " << sorted_keys_pos << endl; + << " # " << sorted_keys_pos << '\n'; sorted_keys_pos++; } indent_down(); - indent(out) << ")" << endl; + indent(out) << ")" << '\n'; } else { - indent(out) << tstruct->get_name() << ".thrift_spec = ()" << endl; + indent(out) << tstruct->get_name() << ".thrift_spec = ()" << '\n'; } } @@ -786,7 +808,7 @@ void t_py_generator::generate_py_struct_definition(ostream& out, const vector& sorted_members = tstruct->get_sorted_members(); vector::const_iterator m_iter; - out << endl << endl << "class " << tstruct->get_name(); + out << '\n' << '\n' << "class " << tstruct->get_name(); if (is_exception) { if (gen_dynamic_) { if (is_immutable(tstruct)) { @@ -806,11 +828,13 @@ void t_py_generator::generate_py_struct_definition(ostream& out, } else if (gen_newstyle_) { out << "(object)"; } - out << ":" << endl; + out << ":" << '\n'; indent_up(); generate_python_docstring(out, tstruct); + std::string thrift_spec_type = gen_type_hints_ ? ": typing.Any" : ""; + out << indent() << "thrift_spec" << thrift_spec_type << " = None" << '\n'; - out << endl; + out << '\n'; /* Here we generate the structure specification for the fastbinary codec. @@ -833,13 +857,13 @@ void t_py_generator::generate_py_struct_definition(ostream& out, */ if (gen_slots_) { - indent(out) << "__slots__ = (" << endl; + indent(out) << "__slots__ = (" << '\n'; indent_up(); for (m_iter = sorted_members.begin(); m_iter != sorted_members.end(); ++m_iter) { - indent(out) << "'" << (*m_iter)->get_name() << "'," << endl; + indent(out) << "'" << (*m_iter)->get_name() << "'," << '\n'; } indent_down(); - indent(out) << ")" << endl << endl; + indent(out) << ")" << '\n' << '\n'; } // TODO(dreiss): Look into generating an empty tuple instead of None @@ -848,13 +872,13 @@ void t_py_generator::generate_py_struct_definition(ostream& out, // don't have thrift_spec. if (members.size() > 0) { - out << endl; + out << '\n'; out << indent() << "def __init__(self,"; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { out << " " << declare_argument(*m_iter) << ","; } - out << "):" << endl; + out << "):" << '\n'; indent_up(); @@ -863,10 +887,10 @@ void t_py_generator::generate_py_struct_definition(ostream& out, t_type* type = (*m_iter)->get_type(); if (!type->is_base_type() && !type->is_enum() && (*m_iter)->get_value() != nullptr) { indent(out) << "if " << (*m_iter)->get_name() << " is " - << "self.thrift_spec[" << (*m_iter)->get_key() << "][4]:" << endl; + << "self.thrift_spec[" << (*m_iter)->get_key() << "][4]:" << '\n'; indent_up(); indent(out) << (*m_iter)->get_name() << " = " << render_field_default_value(*m_iter) - << endl; + << '\n'; indent_down(); } @@ -875,16 +899,18 @@ void t_py_generator::generate_py_struct_definition(ostream& out, indent(out) << "super(" << tstruct->get_name() << ", self).__setattr__('" << (*m_iter)->get_name() << "', " << (*m_iter)->get_name() << " if hasattr(" << (*m_iter)->get_name() << ", 'value') else " - << type_name(type) << ".__members__.get(" << (*m_iter)->get_name() << "))" << endl; + << type_name(type) << ".__members__.get(" << (*m_iter)->get_name() << "))" << '\n'; } else if (gen_newstyle_ || gen_dynamic_) { indent(out) << "super(" << tstruct->get_name() << ", self).__setattr__('" - << (*m_iter)->get_name() << "', " << (*m_iter)->get_name() << ")" << endl; + << (*m_iter)->get_name() << "', " << (*m_iter)->get_name() << ")" << '\n'; } else { indent(out) << "self.__dict__['" << (*m_iter)->get_name() - << "'] = " << (*m_iter)->get_name() << endl; + << "'] = " << (*m_iter)->get_name() << '\n'; } } else { - indent(out) << "self." << (*m_iter)->get_name() << " = " << (*m_iter)->get_name() << endl; + indent(out) << "self." << (*m_iter)->get_name() + << member_hint((*m_iter)->get_type(), (*m_iter)->get_req()) << " = " + << (*m_iter)->get_name() << '\n'; } } @@ -892,8 +918,8 @@ void t_py_generator::generate_py_struct_definition(ostream& out, } if (is_immutable(tstruct)) { - out << endl; - out << indent() << "def __setattr__(self, *args):" << endl; + out << '\n'; + out << indent() << "def __setattr__(self, *args):" << '\n'; indent_up(); // Not user-provided fields should be editable so that the Python Standard Library can edit @@ -902,16 +928,16 @@ void t_py_generator::generate_py_struct_definition(ostream& out, // trivial because we know which fields are user-provided, without slots we need to build a // way to know which fields are user-provided. if (gen_slots_ && !gen_dynamic_) { - out << indent() << "if args[0] not in self.__slots__:" << endl; + out << indent() << "if args[0] not in self.__slots__:" << '\n'; indent_up(); - out << indent() << "super().__setattr__(*args)" << endl - << indent() << "return" << endl; + out << indent() << "super().__setattr__(*args)" << '\n' + << indent() << "return" << '\n'; indent_down(); } - out << indent() << "raise TypeError(\"can't modify immutable instance\")" << endl; + out << indent() << "raise TypeError(\"can't modify immutable instance\")" << '\n'; indent_down(); - out << endl; - out << indent() << "def __delattr__(self, *args):" << endl; + out << '\n'; + out << indent() << "def __delattr__(self, *args):" << '\n'; indent_up(); // Not user-provided fields should be editable so that the Python Standard Library can edit @@ -920,26 +946,26 @@ void t_py_generator::generate_py_struct_definition(ostream& out, // trivial because we know which fields are user-provided, without slots we need to build a // way to know which fields are user-provided. if (gen_slots_ && !gen_dynamic_) { - out << indent() << "if args[0] not in self.__slots__:" << endl; + out << indent() << "if args[0] not in self.__slots__:" << '\n'; indent_up(); - out << indent() << "super().__delattr__(*args)" << endl - << indent() << "return" << endl; + out << indent() << "super().__delattr__(*args)" << '\n' + << indent() << "return" << '\n'; indent_down(); } - out << indent() << "raise TypeError(\"can't modify immutable instance\")" << endl; + out << indent() << "raise TypeError(\"can't modify immutable instance\")" << '\n'; indent_down(); - out << endl; + out << '\n'; // Hash all of the members in order, and also hash in the class // to avoid collisions for stuff like single-field structures. - out << indent() << "def __hash__(self):" << endl + out << indent() << "def __hash__(self):" << '\n' << indent() << indent_str() << "return hash(self.__class__) ^ hash(("; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { out << "self." << (*m_iter)->get_name() << ", "; } - out << "))" << endl; + out << "))" << '\n'; } else if (gen_enum_) { bool has_enum = false; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { @@ -951,25 +977,25 @@ void t_py_generator::generate_py_struct_definition(ostream& out, } if (has_enum) { - out << endl; - indent(out) << "def __setattr__(self, name, value):" << endl; + out << '\n'; + indent(out) << "def __setattr__(self, name, value):" << '\n'; indent_up(); for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { t_type* type = (*m_iter)->get_type(); if (type->is_enum()) { - out << indent() << "if name == \"" << (*m_iter)->get_name() << "\":" << endl + out << indent() << "if name == \"" << (*m_iter)->get_name() << "\":" << '\n' << indent() << indent_str() << "super().__setattr__(name, value if hasattr(value, 'value') else " - << type_name(type) << ".__members__.get(value))" << endl - << indent() << indent_str() << "return" << endl; + << type_name(type) << ".__members__.get(value))" << '\n' + << indent() << indent_str() << "return" << '\n'; } } - indent(out) << "super().__setattr__(name, value)" << endl << endl; + indent(out) << "super().__setattr__(name, value)" << '\n' << '\n'; indent_down(); } } if (!gen_dynamic_) { - out << endl; + out << '\n'; generate_py_struct_reader(out, tstruct); generate_py_struct_writer(out, tstruct); } @@ -978,64 +1004,64 @@ void t_py_generator::generate_py_struct_definition(ostream& out, // because when raised exceptions are printed to the console, __repr__ // isn't used. See python bug #5882 if (is_exception) { - out << endl; - out << indent() << "def __str__(self):" << endl - << indent() << indent_str() << "return repr(self)" << endl; + out << '\n'; + out << indent() << "def __str__(self):" << '\n' + << indent() << indent_str() << "return repr(self)" << '\n'; } if (!gen_slots_) { - out << endl; + out << '\n'; // Printing utilities so that on the command line thrift // structs look pretty like dictionaries - indent(out) << "def __repr__(self):" << endl; + indent(out) << "def __repr__(self):" << '\n'; indent_up(); - out << indent() << "L = ['%s=%r' % (key, value)" << endl - << indent() << " for key, value in self.__dict__.items()]" << endl - << indent() << "return '%s(%s)' % (self.__class__.__name__, ', '.join(L))" << endl - << endl; + out << indent() << "L = ['%s=%r' % (key, value)" << '\n' + << indent() << " for key, value in self.__dict__.items()]" << '\n' + << indent() << "return '%s(%s)' % (self.__class__.__name__, ', '.join(L))" << '\n' + << '\n'; indent_down(); // Equality and inequality methods that compare by value - out << indent() << "def __eq__(self, other):" << endl; + out << indent() << "def __eq__(self, other):" << '\n'; indent_up(); out << indent() << "return isinstance(other, self.__class__) and " - "self.__dict__ == other.__dict__" << endl; + "self.__dict__ == other.__dict__" << '\n'; indent_down(); - out << endl; + out << '\n'; - out << indent() << "def __ne__(self, other):" << endl; + out << indent() << "def __ne__(self, other):" << '\n'; indent_up(); - out << indent() << "return not (self == other)" << endl; + out << indent() << "return not (self == other)" << '\n'; indent_down(); } else if (!gen_dynamic_) { - out << endl; + out << '\n'; // no base class available to implement __eq__ and __repr__ and __ne__ for us // so we must provide one that uses __slots__ - indent(out) << "def __repr__(self):" << endl; + indent(out) << "def __repr__(self):" << '\n'; indent_up(); - out << indent() << "L = ['%s=%r' % (key, getattr(self, key))" << endl - << indent() << " for key in self.__slots__]" << endl - << indent() << "return '%s(%s)' % (self.__class__.__name__, ', '.join(L))" << endl - << endl; + out << indent() << "L = ['%s=%r' % (key, getattr(self, key))" << '\n' + << indent() << " for key in self.__slots__]" << '\n' + << indent() << "return '%s(%s)' % (self.__class__.__name__, ', '.join(L))" << '\n' + << '\n'; indent_down(); // Equality method that compares each attribute by value and type, walking __slots__ - out << indent() << "def __eq__(self, other):" << endl; + out << indent() << "def __eq__(self, other):" << '\n'; indent_up(); - out << indent() << "if not isinstance(other, self.__class__):" << endl - << indent() << indent_str() << "return False" << endl - << indent() << "for attr in self.__slots__:" << endl - << indent() << indent_str() << "my_val = getattr(self, attr)" << endl - << indent() << indent_str() << "other_val = getattr(other, attr)" << endl - << indent() << indent_str() << "if my_val != other_val:" << endl - << indent() << indent_str() << indent_str() << "return False" << endl - << indent() << "return True" << endl - << endl; + out << indent() << "if not isinstance(other, self.__class__):" << '\n' + << indent() << indent_str() << "return False" << '\n' + << indent() << "for attr in self.__slots__:" << '\n' + << indent() << indent_str() << "my_val = getattr(self, attr)" << '\n' + << indent() << indent_str() << "other_val = getattr(other, attr)" << '\n' + << indent() << indent_str() << "if my_val != other_val:" << '\n' + << indent() << indent_str() << indent_str() << "return False" << '\n' + << indent() << "return True" << '\n' + << '\n'; indent_down(); - out << indent() << "def __ne__(self, other):" << endl - << indent() << indent_str() << "return not (self == other)" << endl; + out << indent() << "def __ne__(self, other):" << '\n' + << indent() << indent_str() << "return not (self == other)" << '\n'; } indent_down(); } @@ -1048,9 +1074,9 @@ void t_py_generator::generate_py_struct_reader(ostream& out, t_struct* tstruct) vector::const_iterator f_iter; if (is_immutable(tstruct)) { - out << indent() << "@classmethod" << endl << indent() << "def read(cls, iprot):" << endl; + out << indent() << "@classmethod" << '\n' << indent() << "def read(cls, iprot):" << '\n'; } else { - indent(out) << "def read(self, iprot):" << endl; + indent(out) << "def read(self, iprot):" << '\n'; } indent_up(); @@ -1059,18 +1085,18 @@ void t_py_generator::generate_py_struct_reader(ostream& out, t_struct* tstruct) indent(out) << "if iprot._fast_decode is not None " "and isinstance(iprot.trans, TTransport.CReadableTransport) " "and " - << id << ".thrift_spec is not None:" << endl; + << id << ".thrift_spec is not None:" << '\n'; indent_up(); if (is_immutable(tstruct)) { - indent(out) << "return iprot._fast_decode(None, iprot, [cls, cls.thrift_spec])" << endl; + indent(out) << "return iprot._fast_decode(None, iprot, [cls, cls.thrift_spec])" << '\n'; } else { - indent(out) << "iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])" << endl; - indent(out) << "return" << endl; + indent(out) << "iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])" << '\n'; + indent(out) << "return" << '\n'; } indent_down(); - indent(out) << "iprot.readStructBegin()" << endl; + indent(out) << "iprot.readStructBegin()" << '\n'; if (is_immutable(tstruct)) { for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { @@ -1082,21 +1108,21 @@ void t_py_generator::generate_py_struct_reader(ostream& out, t_struct* tstruct) } else { result << "None"; } - indent(out) << result.str() << endl; + indent(out) << result.str() << '\n'; } } // Loop over reading in fields - indent(out) << "while True:" << endl; + indent(out) << "while True:" << '\n'; indent_up(); // Read beginning field marker - indent(out) << "(fname, ftype, fid) = iprot.readFieldBegin()" << endl; + indent(out) << "(fname, ftype, fid) = iprot.readFieldBegin()" << '\n'; // Check for field STOP marker and break - indent(out) << "if ftype == TType.STOP:" << endl; + indent(out) << "if ftype == TType.STOP:" << '\n'; indent_up(); - indent(out) << "break" << endl; + indent(out) << "break" << '\n'; indent_down(); // Switch statement on the field we are reading @@ -1110,9 +1136,9 @@ void t_py_generator::generate_py_struct_reader(ostream& out, t_struct* tstruct) } else { out << indent() << "elif "; } - out << "fid == " << (*f_iter)->get_key() << ":" << endl; + out << "fid == " << (*f_iter)->get_key() << ":" << '\n'; indent_up(); - indent(out) << "if ftype == " << type_to_enum((*f_iter)->get_type()) << ":" << endl; + indent(out) << "if ftype == " << type_to_enum((*f_iter)->get_type()) << ":" << '\n'; indent_up(); if (is_immutable(tstruct)) { generate_deserialize_field(out, *f_iter); @@ -1120,32 +1146,32 @@ void t_py_generator::generate_py_struct_reader(ostream& out, t_struct* tstruct) generate_deserialize_field(out, *f_iter, "self."); } indent_down(); - out << indent() << "else:" << endl << indent() << indent_str() << "iprot.skip(ftype)" << endl; + out << indent() << "else:" << '\n' << indent() << indent_str() << "iprot.skip(ftype)" << '\n'; indent_down(); } // In the default case we skip the field - out << indent() << "else:" << endl << indent() << indent_str() << "iprot.skip(ftype)" << endl; + out << indent() << "else:" << '\n' << indent() << indent_str() << "iprot.skip(ftype)" << '\n'; // Read field end marker - indent(out) << "iprot.readFieldEnd()" << endl; + indent(out) << "iprot.readFieldEnd()" << '\n'; indent_down(); - indent(out) << "iprot.readStructEnd()" << endl; + indent(out) << "iprot.readStructEnd()" << '\n'; if (is_immutable(tstruct)) { - indent(out) << "return cls(" << endl; + indent(out) << "return cls(" << '\n'; indent_up(); for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { - indent(out) << (*f_iter)->get_name() << "=" << (*f_iter)->get_name() << "," << endl; + indent(out) << (*f_iter)->get_name() << "=" << (*f_iter)->get_name() << "," << '\n'; } indent_down(); - indent(out) << ")" << endl; + indent(out) << ")" << '\n'; } indent_down(); - out << endl; + out << '\n'; } void t_py_generator::generate_py_struct_writer(ostream& out, t_struct* tstruct) { @@ -1153,49 +1179,49 @@ void t_py_generator::generate_py_struct_writer(ostream& out, t_struct* tstruct) const vector& fields = tstruct->get_sorted_members(); vector::const_iterator f_iter; - indent(out) << "def write(self, oprot):" << endl; + indent(out) << "def write(self, oprot):" << '\n'; indent_up(); - - indent(out) << "if oprot._fast_encode is not None and self.thrift_spec is not None:" << endl; + indent(out) << "self.validate()" << '\n'; + indent(out) << "if oprot._fast_encode is not None and self.thrift_spec is not None:" << '\n'; indent_up(); indent(out) << "oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))" - << endl; - indent(out) << "return" << endl; + << '\n'; + indent(out) << "return" << '\n'; indent_down(); - indent(out) << "oprot.writeStructBegin('" << name << "')" << endl; + indent(out) << "oprot.writeStructBegin('" << name << "')" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { // Write field header - indent(out) << "if self." << (*f_iter)->get_name() << " is not None:" << endl; + indent(out) << "if self." << (*f_iter)->get_name() << " is not None:" << '\n'; indent_up(); indent(out) << "oprot.writeFieldBegin(" << "'" << (*f_iter)->get_name() << "', " << type_to_enum((*f_iter)->get_type()) - << ", " << (*f_iter)->get_key() << ")" << endl; + << ", " << (*f_iter)->get_key() << ")" << '\n'; // Write field contents generate_serialize_field(out, *f_iter, "self."); // Write field closer - indent(out) << "oprot.writeFieldEnd()" << endl; + indent(out) << "oprot.writeFieldEnd()" << '\n'; indent_down(); } // Write the struct map - out << indent() << "oprot.writeFieldStop()" << endl << indent() << "oprot.writeStructEnd()" - << endl; + out << indent() << "oprot.writeFieldStop()" << '\n' << indent() << "oprot.writeStructEnd()" + << '\n'; - out << endl; + out << '\n'; indent_down(); generate_py_struct_required_validator(out, tstruct); } void t_py_generator::generate_py_struct_required_validator(ostream& out, t_struct* tstruct) { - indent(out) << "def validate(self):" << endl; + indent(out) << "def validate(self):" << '\n'; indent_up(); const vector& fields = tstruct->get_members(); @@ -1206,14 +1232,14 @@ void t_py_generator::generate_py_struct_required_validator(ostream& out, t_struc for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { t_field* field = (*f_iter); if (field->get_req() == t_field::T_REQUIRED) { - indent(out) << "if self." << field->get_name() << " is None:" << endl; + indent(out) << "if self." << field->get_name() << " is None:" << '\n'; indent(out) << indent_str() << "raise TProtocolException(message='Required field " - << field->get_name() << " is unset!')" << endl; + << field->get_name() << " is unset!')" << '\n'; } } } - indent(out) << "return" << endl; + indent(out) << "return" << '\n'; indent_down(); } @@ -1226,32 +1252,32 @@ void t_py_generator::generate_service(t_service* tservice) { string f_service_name = package_dir_ + "/" + service_name_ + ".py"; f_service_.open(f_service_name.c_str()); - f_service_ << py_autogen_comment() << endl << py_imports() << endl; + f_service_ << py_autogen_comment() << '\n' << py_imports() << '\n'; if (tservice->get_extends() != nullptr) { f_service_ << "import " << get_real_py_module(tservice->get_extends()->get_program(), gen_twisted_, package_prefix_) << "." - << tservice->get_extends()->get_name() << endl; + << tservice->get_extends()->get_name() << '\n'; } - f_service_ << "import logging" << endl - << "from .ttypes import *" << endl - << "from thrift.Thrift import TProcessor" << endl - << "from thrift.transport import TTransport" << endl + f_service_ << "import logging" << '\n' + << "from .ttypes import *" << '\n' + << "from thrift.Thrift import TProcessor" << '\n' + << "from thrift.transport import TTransport" << '\n' << import_dynbase_; if (gen_zope_interface_) { - f_service_ << "from zope.interface import Interface, implementer" << endl; + f_service_ << "from zope.interface import Interface, implementer" << '\n'; } if (gen_twisted_) { - f_service_ << "from twisted.internet import defer" << endl - << "from thrift.transport import TTwisted" << endl; + f_service_ << "from twisted.internet import defer" << '\n' + << "from thrift.transport import TTwisted" << '\n'; } else if (gen_tornado_) { - f_service_ << "from tornado import gen" << endl; - f_service_ << "from tornado import concurrent" << endl; + f_service_ << "from tornado import gen" << '\n'; + f_service_ << "from tornado import concurrent" << '\n'; } - f_service_ << "all_structs = []" << endl; + f_service_ << "all_structs = []" << '\n'; // Generate the three main parts of the service generate_service_interface(tservice); @@ -1261,8 +1287,8 @@ void t_py_generator::generate_service(t_service* tservice) { generate_service_remote(tservice); // Close service file - f_service_ << "fix_spec(all_structs)" << endl - << "del all_structs" << endl; + f_service_ << "fix_spec(all_structs)" << '\n' + << "del all_structs" << '\n'; f_service_.close(); } @@ -1275,7 +1301,7 @@ void t_py_generator::generate_service_helpers(t_service* tservice) { vector functions = tservice->get_functions(); vector::iterator f_iter; - f_service_ << endl << "# HELPER FUNCTIONS AND STRUCTURES" << endl; + f_service_ << '\n' << "# HELPER FUNCTIONS AND STRUCTURES" << '\n'; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { t_struct* ts = (*f_iter)->get_arglist(); @@ -1328,12 +1354,12 @@ void t_py_generator::generate_service_interface(t_service* tservice) { } } - f_service_ << endl << endl << "class Iface" << extends_if << ":" << endl; + f_service_ << '\n' << '\n' << "class Iface" << extends_if << ":" << '\n'; indent_up(); generate_python_docstring(f_service_, tservice); vector functions = tservice->get_functions(); if (functions.empty()) { - f_service_ << indent() << "pass" << endl; + f_service_ << indent() << "pass" << '\n'; } else { vector::iterator f_iter; bool first = true; @@ -1341,12 +1367,12 @@ void t_py_generator::generate_service_interface(t_service* tservice) { if (first) { first = false; } else { - f_service_ << endl; + f_service_ << '\n'; } - f_service_ << indent() << "def " << function_signature(*f_iter, true) << ":" << endl; + f_service_ << indent() << "def " << function_signature(*f_iter, true) << ":" << '\n'; indent_up(); generate_python_docstring(f_service_, (*f_iter)); - f_service_ << indent() << "pass" << endl; + f_service_ << indent() << "pass" << '\n'; indent_down(); } } @@ -1375,91 +1401,91 @@ void t_py_generator::generate_service_client(t_service* tservice) { } } - f_service_ << endl << endl; + f_service_ << '\n' << '\n'; if (gen_zope_interface_) { - f_service_ << "@implementer(Iface)" << endl - << "class Client" << extends_client << ":" << endl - << endl; + f_service_ << "@implementer(Iface)" << '\n' + << "class Client" << extends_client << ":" << '\n' + << '\n'; } else { - f_service_ << "class Client(" << extends_client << "Iface):" << endl; + f_service_ << "class Client(" << extends_client << "Iface):" << '\n'; } indent_up(); generate_python_docstring(f_service_, tservice); // Constructor function if (gen_twisted_) { - f_service_ << indent() << "def __init__(self, transport, oprot_factory):" << endl; + f_service_ << indent() << "def __init__(self, transport, oprot_factory):" << '\n'; } else if (gen_tornado_) { f_service_ << indent() - << "def __init__(self, transport, iprot_factory, oprot_factory=None):" << endl; + << "def __init__(self, transport, iprot_factory, oprot_factory=None):" << '\n'; } else { - f_service_ << indent() << "def __init__(self, iprot, oprot=None):" << endl; + f_service_ << indent() << "def __init__(self, iprot, oprot=None):" << '\n'; } indent_up(); if (extends.empty()) { if (gen_twisted_) { - f_service_ << indent() << "self._transport = transport" << endl - << indent() << "self._oprot_factory = oprot_factory" << endl - << indent() << "self._seqid = 0" << endl - << indent() << "self._reqs = {}" << endl; + f_service_ << indent() << "self._transport = transport" << '\n' + << indent() << "self._oprot_factory = oprot_factory" << '\n' + << indent() << "self._seqid = 0" << '\n' + << indent() << "self._reqs = {}" << '\n'; } else if (gen_tornado_) { - f_service_ << indent() << "self._transport = transport" << endl - << indent() << "self._iprot_factory = iprot_factory" << endl + f_service_ << indent() << "self._transport = transport" << '\n' + << indent() << "self._iprot_factory = iprot_factory" << '\n' << indent() << "self._oprot_factory = (oprot_factory if oprot_factory is not None" - << endl - << indent() << " else iprot_factory)" << endl - << indent() << "self._seqid = 0" << endl - << indent() << "self._reqs = {}" << endl + << '\n' + << indent() << " else iprot_factory)" << '\n' + << indent() << "self._seqid = 0" << '\n' + << indent() << "self._reqs = {}" << '\n' << indent() << "self._transport.io_loop.spawn_callback(self._start_receiving)" - << endl; + << '\n'; } else { - f_service_ << indent() << "self._iprot = self._oprot = iprot" << endl - << indent() << "if oprot is not None:" << endl - << indent() << indent_str() << "self._oprot = oprot" << endl - << indent() << "self._seqid = 0" << endl; + f_service_ << indent() << "self._iprot = self._oprot = iprot" << '\n' + << indent() << "if oprot is not None:" << '\n' + << indent() << indent_str() << "self._oprot = oprot" << '\n' + << indent() << "self._seqid = 0" << '\n'; } } else { if (gen_twisted_) { f_service_ << indent() << extends - << ".Client.__init__(self, transport, oprot_factory)" << endl; + << ".Client.__init__(self, transport, oprot_factory)" << '\n'; } else if (gen_tornado_) { f_service_ << indent() << extends - << ".Client.__init__(self, transport, iprot_factory, oprot_factory)" << endl; + << ".Client.__init__(self, transport, iprot_factory, oprot_factory)" << '\n'; } else { - f_service_ << indent() << extends << ".Client.__init__(self, iprot, oprot)" << endl; + f_service_ << indent() << extends << ".Client.__init__(self, iprot, oprot)" << '\n'; } } indent_down(); if (gen_tornado_ && extends.empty()) { - f_service_ << endl << - indent() << "@gen.engine" << endl << - indent() << "def _start_receiving(self):" << endl; + f_service_ << '\n' << + indent() << "@gen.coroutine" << '\n' << + indent() << "def _start_receiving(self):" << '\n'; indent_up(); - indent(f_service_) << "while True:" << endl; + indent(f_service_) << "while True:" << '\n'; indent_up(); - f_service_ << indent() << "try:" << endl - << indent() << indent_str() << "frame = yield self._transport.readFrame()" << endl - << indent() << "except TTransport.TTransportException as e:" << endl - << indent() << indent_str() << "for future in self._reqs.values():" << endl - << indent() << indent_str() << indent_str() << "future.set_exception(e)" << endl - << indent() << indent_str() << "self._reqs = {}" << endl - << indent() << indent_str() << "return" << endl - << indent() << "tr = TTransport.TMemoryBuffer(frame)" << endl - << indent() << "iprot = self._iprot_factory.getProtocol(tr)" << endl - << indent() << "(fname, mtype, rseqid) = iprot.readMessageBegin()" << endl - << indent() << "method = getattr(self, 'recv_' + fname)" << endl - << indent() << "future = self._reqs.pop(rseqid, None)" << endl - << indent() << "if not future:" << endl - << indent() << indent_str() << "# future has already been discarded" << endl - << indent() << indent_str() << "continue" << endl - << indent() << "try:" << endl - << indent() << indent_str() << "result = method(iprot, mtype, rseqid)" << endl - << indent() << "except Exception as e:" << endl - << indent() << indent_str() << "future.set_exception(e)" << endl - << indent() << "else:" << endl - << indent() << indent_str() << "future.set_result(result)" << endl; + f_service_ << indent() << "try:" << '\n' + << indent() << indent_str() << "frame = yield self._transport.readFrame()" << '\n' + << indent() << "except TTransport.TTransportException as e:" << '\n' + << indent() << indent_str() << "for future in self._reqs.values():" << '\n' + << indent() << indent_str() << indent_str() << "future.set_exception(e)" << '\n' + << indent() << indent_str() << "self._reqs = {}" << '\n' + << indent() << indent_str() << "return" << '\n' + << indent() << "tr = TTransport.TMemoryBuffer(frame)" << '\n' + << indent() << "iprot = self._iprot_factory.getProtocol(tr)" << '\n' + << indent() << "(fname, mtype, rseqid) = iprot.readMessageBegin()" << '\n' + << indent() << "method = getattr(self, 'recv_' + fname)" << '\n' + << indent() << "future = self._reqs.pop(rseqid, None)" << '\n' + << indent() << "if not future:" << '\n' + << indent() << indent_str() << "# future has already been discarded" << '\n' + << indent() << indent_str() << "continue" << '\n' + << indent() << "try:" << '\n' + << indent() << indent_str() << "result = method(iprot, mtype, rseqid)" << '\n' + << indent() << "except Exception as e:" << '\n' + << indent() << indent_str() << "future.set_exception(e)" << '\n' + << indent() << "else:" << '\n' + << indent() << indent_str() << "future.set_result(result)" << '\n'; indent_down(); indent_down(); } @@ -1473,20 +1499,20 @@ void t_py_generator::generate_service_client(t_service* tservice) { vector::const_iterator fld_iter; string funname = (*f_iter)->get_name(); - f_service_ << endl; + f_service_ << '\n'; // Open function - indent(f_service_) << "def " << function_signature(*f_iter, false) << ":" << endl; + indent(f_service_) << "def " << function_signature(*f_iter, false) << ":" << '\n'; indent_up(); generate_python_docstring(f_service_, (*f_iter)); if (gen_twisted_) { - indent(f_service_) << "seqid = self._seqid = self._seqid + 1" << endl; - indent(f_service_) << "self._reqs[seqid] = defer.Deferred()" << endl << endl; + indent(f_service_) << "seqid = self._seqid = self._seqid + 1" << '\n'; + indent(f_service_) << "self._reqs[seqid] = defer.Deferred()" << '\n' << '\n'; indent(f_service_) << "d = defer.maybeDeferred(self.send_" << funname; } else if (gen_tornado_) { - indent(f_service_) << "self._seqid += 1" << endl; + indent(f_service_) << "self._seqid += 1" << '\n'; if (!(*f_iter)->is_oneway()) { - indent(f_service_) << "future = self._reqs[self._seqid] = concurrent.Future()" << endl; + indent(f_service_) << "future = self._reqs[self._seqid] = concurrent.Future()" << '\n'; } indent(f_service_) << "self.send_" << funname << "("; @@ -1509,19 +1535,19 @@ void t_py_generator::generate_service_client(t_service* tservice) { f_service_ << (*fld_iter)->get_name(); } - f_service_ << ")" << endl; + f_service_ << ")" << '\n'; if (!(*f_iter)->is_oneway()) { if (gen_twisted_) { // nothing. See the next block. } else if (gen_tornado_) { - indent(f_service_) << "return future" << endl; + indent(f_service_) << "return future" << '\n'; } else { f_service_ << indent(); if (!(*f_iter)->get_returntype()->is_void()) { f_service_ << "return "; } - f_service_ << "self.recv_" << funname << "()" << endl; + f_service_ << "self.recv_" << funname << "()" << '\n'; } } indent_down(); @@ -1529,40 +1555,40 @@ void t_py_generator::generate_service_client(t_service* tservice) { if (gen_twisted_) { // This block injects the body of the send_<> method for twisted (and a cb/eb pair) indent_up(); - indent(f_service_) << "d.addCallbacks(" << endl; + indent(f_service_) << "d.addCallbacks(" << '\n'; indent_up(); - f_service_ << indent() << "callback=self.cb_send_" << funname << "," << endl << indent() - << "callbackArgs=(seqid,)," << endl << indent() << "errback=self.eb_send_" - << funname << "," << endl << indent() << "errbackArgs=(seqid,))" << endl; + f_service_ << indent() << "callback=self.cb_send_" << funname << "," << '\n' << indent() + << "callbackArgs=(seqid,)," << '\n' << indent() << "errback=self.eb_send_" + << funname << "," << '\n' << indent() << "errbackArgs=(seqid,))" << '\n'; indent_down(); - indent(f_service_) << "return d" << endl; + indent(f_service_) << "return d" << '\n'; indent_down(); - f_service_ << endl; + f_service_ << '\n'; - indent(f_service_) << "def cb_send_" << funname << "(self, _, seqid):" << endl; + indent(f_service_) << "def cb_send_" << funname << "(self, _, seqid):" << '\n'; indent_up(); if ((*f_iter)->is_oneway()) { // if one-way, fire the deferred & remove it from _reqs - f_service_ << indent() << "d = self._reqs.pop(seqid)" << endl << indent() - << "d.callback(None)" << endl << indent() << "return d" << endl; + f_service_ << indent() << "d = self._reqs.pop(seqid)" << '\n' << indent() + << "d.callback(None)" << '\n' << indent() << "return d" << '\n'; } else { - f_service_ << indent() << "return self._reqs[seqid]" << endl; + f_service_ << indent() << "return self._reqs[seqid]" << '\n'; } indent_down(); - f_service_ << endl; + f_service_ << '\n'; // add an errback to fail the request if the call to send_<> raised an exception - indent(f_service_) << "def eb_send_" << funname << "(self, f, seqid):" << endl; + indent(f_service_) << "def eb_send_" << funname << "(self, f, seqid):" << '\n'; indent_up(); - f_service_ << indent() << "d = self._reqs.pop(seqid)" << endl << indent() << "d.errback(f)" - << endl << indent() << "return d" << endl; + f_service_ << indent() << "d = self._reqs.pop(seqid)" << '\n' << indent() << "d.errback(f)" + << '\n' << indent() << "return d" << '\n'; indent_down(); } - f_service_ << endl; - indent(f_service_) << "def send_" << function_signature(*f_iter, false) << ":" << endl; + f_service_ << '\n'; + indent(f_service_) << "def send_" << function_signature(*f_iter, false, true) << ":" << '\n'; indent_up(); std::string argsname = (*f_iter)->get_name() + "_args"; @@ -1570,29 +1596,29 @@ void t_py_generator::generate_service_client(t_service* tservice) { // Serialize the request header if (gen_twisted_ || gen_tornado_) { - f_service_ << indent() << "oprot = self._oprot_factory.getProtocol(self._transport)" << endl + f_service_ << indent() << "oprot = self._oprot_factory.getProtocol(self._transport)" << '\n' << indent() << "oprot.writeMessageBegin('" << (*f_iter)->get_name() << "', " - << messageType << ", self._seqid)" << endl; + << messageType << ", self._seqid)" << '\n'; } else { f_service_ << indent() << "self._oprot.writeMessageBegin('" << (*f_iter)->get_name() << "', " - << messageType << ", self._seqid)" << endl; + << messageType << ", self._seqid)" << '\n'; } - f_service_ << indent() << "args = " << argsname << "()" << endl; + f_service_ << indent() << "args = " << argsname << "()" << '\n'; for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) { f_service_ << indent() << "args." << (*fld_iter)->get_name() << " = " - << (*fld_iter)->get_name() << endl; + << (*fld_iter)->get_name() << '\n'; } // Write to the stream if (gen_twisted_ || gen_tornado_) { - f_service_ << indent() << "args.write(oprot)" << endl << indent() << "oprot.writeMessageEnd()" - << endl << indent() << "oprot.trans.flush()" << endl; + f_service_ << indent() << "args.write(oprot)" << '\n' << indent() << "oprot.writeMessageEnd()" + << '\n' << indent() << "oprot.trans.flush()" << '\n'; } else { - f_service_ << indent() << "args.write(self._oprot)" << endl << indent() - << "self._oprot.writeMessageEnd()" << endl << indent() - << "self._oprot.trans.flush()" << endl; + f_service_ << indent() << "args.write(self._oprot)" << '\n' << indent() + << "self._oprot.writeMessageEnd()" << '\n' << indent() + << "self._oprot.trans.flush()" << '\n'; } indent_down(); @@ -1600,51 +1626,51 @@ void t_py_generator::generate_service_client(t_service* tservice) { if (!(*f_iter)->is_oneway()) { std::string resultname = (*f_iter)->get_name() + "_result"; // Open function - f_service_ << endl; + f_service_ << '\n'; if (gen_twisted_ || gen_tornado_) { f_service_ << indent() << "def recv_" << (*f_iter)->get_name() - << "(self, iprot, mtype, rseqid):" << endl; + << "(self, iprot, mtype, rseqid):" << '\n'; } else { t_struct noargs(program_); t_function recv_function((*f_iter)->get_returntype(), string("recv_") + (*f_iter)->get_name(), &noargs); - f_service_ << indent() << "def " << function_signature(&recv_function) << ":" << endl; + f_service_ << indent() << "def " << function_signature(&recv_function) << ":" << '\n'; } indent_up(); // TODO(mcslee): Validate message reply here, seq ids etc. if (gen_twisted_) { - f_service_ << indent() << "d = self._reqs.pop(rseqid)" << endl; + f_service_ << indent() << "d = self._reqs.pop(rseqid)" << '\n'; } else if (gen_tornado_) { } else { - f_service_ << indent() << "iprot = self._iprot" << endl << indent() - << "(fname, mtype, rseqid) = iprot.readMessageBegin()" << endl; + f_service_ << indent() << "iprot = self._iprot" << '\n' << indent() + << "(fname, mtype, rseqid) = iprot.readMessageBegin()" << '\n'; } - f_service_ << indent() << "if mtype == TMessageType.EXCEPTION:" << endl - << indent() << indent_str() << "x = TApplicationException()" << endl; + f_service_ << indent() << "if mtype == TMessageType.EXCEPTION:" << '\n' + << indent() << indent_str() << "x = TApplicationException()" << '\n'; if (gen_twisted_) { - f_service_ << indent() << indent_str() << "x.read(iprot)" << endl << indent() - << indent_str() << "iprot.readMessageEnd()" << endl << indent() << indent_str() << "return d.errback(x)" - << endl << indent() << "result = " << resultname << "()" << endl << indent() - << "result.read(iprot)" << endl << indent() << "iprot.readMessageEnd()" << endl; + f_service_ << indent() << indent_str() << "x.read(iprot)" << '\n' << indent() + << indent_str() << "iprot.readMessageEnd()" << '\n' << indent() << indent_str() << "return d.errback(x)" + << '\n' << indent() << "result = " << resultname << "()" << '\n' << indent() + << "result.read(iprot)" << '\n' << indent() << "iprot.readMessageEnd()" << '\n'; } else { - f_service_ << indent() << indent_str() << "x.read(iprot)" << endl << indent() - << indent_str() << "iprot.readMessageEnd()" << endl << indent() << indent_str() << "raise x" << endl - << indent() << "result = " << resultname << "()" << endl << indent() - << "result.read(iprot)" << endl << indent() << "iprot.readMessageEnd()" << endl; + f_service_ << indent() << indent_str() << "x.read(iprot)" << '\n' << indent() + << indent_str() << "iprot.readMessageEnd()" << '\n' << indent() << indent_str() << "raise x" << '\n' + << indent() << "result = " << resultname << "()" << '\n' << indent() + << "result.read(iprot)" << '\n' << indent() << "iprot.readMessageEnd()" << '\n'; } // Careful, only return _result if not a void function if (!(*f_iter)->get_returntype()->is_void()) { - f_service_ << indent() << "if result.success is not None:" << endl; + f_service_ << indent() << "if result.success is not None:" << '\n'; if (gen_twisted_) { - f_service_ << indent() << indent_str() << "return d.callback(result.success)" << endl; + f_service_ << indent() << indent_str() << "return d.callback(result.success)" << '\n'; } else { - f_service_ << indent() << indent_str() << "return result.success" << endl; + f_service_ << indent() << indent_str() << "return result.success" << '\n'; } } @@ -1653,32 +1679,32 @@ void t_py_generator::generate_service_client(t_service* tservice) { vector::const_iterator x_iter; for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { const string& xname = (*x_iter)->get_name(); - f_service_ << indent() << "if result." << xname << " is not None:" << endl; + f_service_ << indent() << "if result." << xname << " is not None:" << '\n'; if (gen_twisted_) { f_service_ << indent() << indent_str() << "return d.errback(result." << xname << ")" - << endl; + << '\n'; } else { - f_service_ << indent() << indent_str() << "raise result." << xname << "" << endl; + f_service_ << indent() << indent_str() << "raise result." << xname << "" << '\n'; } } // Careful, only return _result if not a void function if ((*f_iter)->get_returntype()->is_void()) { if (gen_twisted_) { - f_service_ << indent() << "return d.callback(None)" << endl; + f_service_ << indent() << "return d.callback(None)" << '\n'; } else { - f_service_ << indent() << "return" << endl; + f_service_ << indent() << "return" << '\n'; } } else { if (gen_twisted_) { f_service_ << indent() << "return d.errback(TApplicationException(TApplicationException.MISSING_RESULT, \"" - << (*f_iter)->get_name() << " failed: unknown result\"))" << endl; + << (*f_iter)->get_name() << " failed: unknown result\"))" << '\n'; } else { f_service_ << indent() << "raise TApplicationException(TApplicationException.MISSING_RESULT, \"" - << (*f_iter)->get_name() << " failed: unknown result\")" << endl; + << (*f_iter)->get_name() << " failed: unknown result\")" << '\n'; } } @@ -1711,29 +1737,27 @@ void t_py_generator::generate_service_remote(t_service* tservice) { f_remote.open(f_remote_name.c_str()); f_remote << - "#!/usr/bin/env python" << endl << - py_autogen_comment() << endl << - "import sys" << endl << - "import pprint" << endl << - "if sys.version_info[0] > 2:" << endl << - indent_str() << "from urllib.parse import urlparse" << endl << - "else:" << endl << - indent_str() << "from urlparse import urlparse" << endl << - "from thrift.transport import TTransport, TSocket, TSSLSocket, THttpClient" << endl << - "from thrift.protocol.TBinaryProtocol import TBinaryProtocol" << endl << - endl; + "#!/usr/bin/env python" << '\n' << + py_autogen_comment() << '\n' << + "import sys" << '\n' << + "import pprint" << '\n' << + "if sys.version_info[0] > 2:" << '\n' << + indent_str() << "from urllib.parse import urlparse" << '\n' << + "else:" << '\n' << + indent_str() << "from urlparse import urlparse" << '\n' << + "from thrift.transport import TTransport, TSocket, TSSLSocket, THttpClient" << '\n' << + "from thrift.protocol.TBinaryProtocol import TBinaryProtocol" << '\n' << '\n'; f_remote << - "from " << module_ << " import " << service_name_ << endl << - "from " << module_ << ".ttypes import *" << endl << - endl; + "from " << module_ << " import " << service_name_ << '\n' << + "from " << module_ << ".ttypes import *" << '\n' << '\n'; f_remote << - "if len(sys.argv) <= 1 or sys.argv[1] == '--help':" << endl << - indent_str() << "print('')" << endl << - indent_str() << "print('Usage: ' + sys.argv[0] + ' [-h host[:port]] [-u url] [-f[ramed]] [-s[sl]] [-novalidate] [-ca_certs certs] [-keyfile keyfile] [-certfile certfile] function [arg1 [arg2...]]')" << endl << - indent_str() << "print('')" << endl << - indent_str() << "print('Functions:')" << endl; + "if len(sys.argv) <= 1 or sys.argv[1] == '--help':" << '\n' << + indent_str() << "print('')" << '\n' << + indent_str() << "print('Usage: ' + sys.argv[0] + ' [-h host[:port]] [-u url] [-f[ramed]] [-s[sl]] [-novalidate] [-ca_certs certs] [-keyfile keyfile] [-certfile certfile] function [arg1 [arg2...]]')" << '\n' << + indent_str() << "print('')" << '\n' << + indent_str() << "print('Functions:')" << '\n'; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { f_remote << indent_str() << "print(' " << (*f_iter)->get_returntype()->get_name() << " " << (*f_iter)->get_name() << "("; @@ -1749,88 +1773,88 @@ void t_py_generator::generate_service_remote(t_service* tservice) { } f_remote << args[i]->get_type()->get_name() << " " << args[i]->get_name(); } - f_remote << ")')" << endl; - } - f_remote << indent_str() << "print('')" << endl << indent_str() << "sys.exit(0)" << endl << endl; - - f_remote << "pp = pprint.PrettyPrinter(indent=2)" << endl - << "host = 'localhost'" << endl - << "port = 9090" << endl - << "uri = ''" << endl - << "framed = False" << endl - << "ssl = False" << endl - << "validate = True" << endl - << "ca_certs = None" << endl - << "keyfile = None" << endl - << "certfile = None" << endl - << "http = False" << endl - << "argi = 1" << endl - << endl - << "if sys.argv[argi] == '-h':" << endl - << indent_str() << "parts = sys.argv[argi + 1].split(':')" << endl - << indent_str() << "host = parts[0]" << endl - << indent_str() << "if len(parts) > 1:" << endl - << indent_str() << indent_str() << "port = int(parts[1])" << endl - << indent_str() << "argi += 2" << endl - << endl - << "if sys.argv[argi] == '-u':" << endl - << indent_str() << "url = urlparse(sys.argv[argi + 1])" << endl - << indent_str() << "parts = url[1].split(':')" << endl - << indent_str() << "host = parts[0]" << endl - << indent_str() << "if len(parts) > 1:" << endl - << indent_str() << indent_str() << "port = int(parts[1])" << endl - << indent_str() << "else:" << endl - << indent_str() << indent_str() << "port = 80" << endl - << indent_str() << "uri = url[2]" << endl - << indent_str() << "if url[4]:" << endl - << indent_str() << indent_str() << "uri += '?%s' % url[4]" << endl - << indent_str() << "http = True" << endl - << indent_str() << "argi += 2" << endl - << endl - << "if sys.argv[argi] == '-f' or sys.argv[argi] == '-framed':" << endl - << indent_str() << "framed = True" << endl - << indent_str() << "argi += 1" << endl - << endl - << "if sys.argv[argi] == '-s' or sys.argv[argi] == '-ssl':" << endl - << indent_str() << "ssl = True" << endl - << indent_str() << "argi += 1" << endl - << endl - << "if sys.argv[argi] == '-novalidate':" << endl - << indent_str() << "validate = False" << endl - << indent_str() << "argi += 1" << endl - << endl - << "if sys.argv[argi] == '-ca_certs':" << endl - << indent_str() << "ca_certs = sys.argv[argi+1]" << endl - << indent_str() << "argi += 2" << endl - << endl - << "if sys.argv[argi] == '-keyfile':" << endl - << indent_str() << "keyfile = sys.argv[argi+1]" << endl - << indent_str() << "argi += 2" << endl - << endl - << "if sys.argv[argi] == '-certfile':" << endl - << indent_str() << "certfile = sys.argv[argi+1]" << endl - << indent_str() << "argi += 2" << endl - << endl - << "cmd = sys.argv[argi]" << endl - << "args = sys.argv[argi + 1:]" << endl - << endl - << "if http:" << endl - << indent_str() << "transport = THttpClient.THttpClient(host, port, uri)" << endl - << "else:" << endl - << indent_str() << "if ssl:" << endl + f_remote << ")')" << '\n'; + } + f_remote << indent_str() << "print('')" << '\n' << indent_str() << "sys.exit(0)" << '\n' << '\n'; + + f_remote << "pp = pprint.PrettyPrinter(indent=2)" << '\n' + << "host = 'localhost'" << '\n' + << "port = 9090" << '\n' + << "uri = ''" << '\n' + << "framed = False" << '\n' + << "ssl = False" << '\n' + << "validate = True" << '\n' + << "ca_certs = None" << '\n' + << "keyfile = None" << '\n' + << "certfile = None" << '\n' + << "http = False" << '\n' + << "argi = 1" << '\n' + << '\n' + << "if sys.argv[argi] == '-h':" << '\n' + << indent_str() << "parts = sys.argv[argi + 1].split(':')" << '\n' + << indent_str() << "host = parts[0]" << '\n' + << indent_str() << "if len(parts) > 1:" << '\n' + << indent_str() << indent_str() << "port = int(parts[1])" << '\n' + << indent_str() << "argi += 2" << '\n' + << '\n' + << "if sys.argv[argi] == '-u':" << '\n' + << indent_str() << "url = urlparse(sys.argv[argi + 1])" << '\n' + << indent_str() << "parts = url[1].split(':')" << '\n' + << indent_str() << "host = parts[0]" << '\n' + << indent_str() << "if len(parts) > 1:" << '\n' + << indent_str() << indent_str() << "port = int(parts[1])" << '\n' + << indent_str() << "else:" << '\n' + << indent_str() << indent_str() << "port = 80" << '\n' + << indent_str() << "uri = url[2]" << '\n' + << indent_str() << "if url[4]:" << '\n' + << indent_str() << indent_str() << "uri += '?%s' % url[4]" << '\n' + << indent_str() << "http = True" << '\n' + << indent_str() << "argi += 2" << '\n' + << '\n' + << "if sys.argv[argi] == '-f' or sys.argv[argi] == '-framed':" << '\n' + << indent_str() << "framed = True" << '\n' + << indent_str() << "argi += 1" << '\n' + << '\n' + << "if sys.argv[argi] == '-s' or sys.argv[argi] == '-ssl':" << '\n' + << indent_str() << "ssl = True" << '\n' + << indent_str() << "argi += 1" << '\n' + << '\n' + << "if sys.argv[argi] == '-novalidate':" << '\n' + << indent_str() << "validate = False" << '\n' + << indent_str() << "argi += 1" << '\n' + << '\n' + << "if sys.argv[argi] == '-ca_certs':" << '\n' + << indent_str() << "ca_certs = sys.argv[argi+1]" << '\n' + << indent_str() << "argi += 2" << '\n' + << '\n' + << "if sys.argv[argi] == '-keyfile':" << '\n' + << indent_str() << "keyfile = sys.argv[argi+1]" << '\n' + << indent_str() << "argi += 2" << '\n' + << '\n' + << "if sys.argv[argi] == '-certfile':" << '\n' + << indent_str() << "certfile = sys.argv[argi+1]" << '\n' + << indent_str() << "argi += 2" << '\n' + << '\n' + << "cmd = sys.argv[argi]" << '\n' + << "args = sys.argv[argi + 1:]" << '\n' + << '\n' + << "if http:" << '\n' + << indent_str() << "transport = THttpClient.THttpClient(host, port, uri)" << '\n' + << "else:" << '\n' + << indent_str() << "if ssl:" << '\n' << indent_str() << indent_str() << "socket = TSSLSocket.TSSLSocket(host, port, " "validate=validate, ca_certs=ca_certs, keyfile=keyfile, certfile=certfile)" - << endl - << indent_str() << "else:" << endl - << indent_str() << indent_str() << "socket = TSocket.TSocket(host, port)" << endl - << indent_str() << "if framed:" << endl - << indent_str() << indent_str() << "transport = TTransport.TFramedTransport(socket)" << endl - << indent_str() << "else:" << endl - << indent_str() << indent_str() << "transport = TTransport.TBufferedTransport(socket)" << endl - << "protocol = TBinaryProtocol(transport)" << endl - << "client = " << service_name_ << ".Client(protocol)" << endl - << "transport.open()" << endl - << endl; + << '\n' + << indent_str() << "else:" << '\n' + << indent_str() << indent_str() << "socket = TSocket.TSocket(host, port)" << '\n' + << indent_str() << "if framed:" << '\n' + << indent_str() << indent_str() << "transport = TTransport.TFramedTransport(socket)" << '\n' + << indent_str() << "else:" << '\n' + << indent_str() << indent_str() << "transport = TTransport.TBufferedTransport(socket)" << '\n' + << "protocol = TBinaryProtocol(transport)" << '\n' + << "client = " << service_name_ << ".Client(protocol)" << '\n' + << "transport.open()" << '\n' + << '\n'; // Generate the dispatch methods bool first = true; @@ -1846,12 +1870,12 @@ void t_py_generator::generate_service_remote(t_service* tservice) { const std::vector& args = arg_struct->get_members(); std::vector::size_type num_args = args.size(); - f_remote << "if cmd == '" << (*f_iter)->get_name() << "':" << endl; + f_remote << "if cmd == '" << (*f_iter)->get_name() << "':" << '\n'; indent_up(); - f_remote << indent() << "if len(args) != " << num_args << ":" << endl + f_remote << indent() << "if len(args) != " << num_args << ":" << '\n' << indent() << indent_str() << "print('" << (*f_iter)->get_name() << " requires " << num_args - << " args')" << endl - << indent() << indent_str() << "sys.exit(1)" << endl + << " args')" << '\n' + << indent() << indent_str() << "sys.exit(1)" << '\n' << indent() << "pp.pprint(client." << (*f_iter)->get_name() << "("; indent_down(); bool first_arg = true; @@ -1866,19 +1890,19 @@ void t_py_generator::generate_service_remote(t_service* tservice) { f_remote << "eval(args[" << i << "]),"; } } - f_remote << "))" << endl; + f_remote << "))" << '\n'; - f_remote << endl; + f_remote << '\n'; } if (functions.size() > 0) { - f_remote << "else:" << endl; - f_remote << indent_str() << "print('Unrecognized method %s' % cmd)" << endl; - f_remote << indent_str() << "sys.exit(1)" << endl; - f_remote << endl; + f_remote << "else:" << '\n'; + f_remote << indent_str() << "print('Unrecognized method %s' % cmd)" << '\n'; + f_remote << indent_str() << "sys.exit(1)" << '\n'; + f_remote << '\n'; } - f_remote << "transport.close()" << endl; + f_remote << "transport.close()" << '\n'; // Close service file f_remote.close(); @@ -1913,100 +1937,100 @@ void t_py_generator::generate_service_server(t_service* tservice) { extends_processor = extends + ".Processor, "; } - f_service_ << endl << endl; + f_service_ << '\n' << '\n'; // Generate the header portion if (gen_zope_interface_) { - f_service_ << "@implementer(Iface)" << endl - << "class Processor(" << extends_processor << "TProcessor):" << endl; + f_service_ << "@implementer(Iface)" << '\n' + << "class Processor(" << extends_processor << "TProcessor):" << '\n'; } else { - f_service_ << "class Processor(" << extends_processor << "Iface, TProcessor):" << endl; + f_service_ << "class Processor(" << extends_processor << "Iface, TProcessor):" << '\n'; } indent_up(); - indent(f_service_) << "def __init__(self, handler):" << endl; + indent(f_service_) << "def __init__(self, handler):" << '\n'; indent_up(); if (extends.empty()) { if (gen_zope_interface_) { - f_service_ << indent() << "self._handler = Iface(handler)" << endl; + f_service_ << indent() << "self._handler = Iface(handler)" << '\n'; } else { - f_service_ << indent() << "self._handler = handler" << endl; + f_service_ << indent() << "self._handler = handler" << '\n'; } - f_service_ << indent() << "self._processMap = {}" << endl; + f_service_ << indent() << "self._processMap = {}" << '\n'; } else { if (gen_zope_interface_) { - f_service_ << indent() << extends << ".Processor.__init__(self, Iface(handler))" << endl; + f_service_ << indent() << extends << ".Processor.__init__(self, Iface(handler))" << '\n'; } else { - f_service_ << indent() << extends << ".Processor.__init__(self, handler)" << endl; + f_service_ << indent() << extends << ".Processor.__init__(self, handler)" << '\n'; } } for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { f_service_ << indent() << "self._processMap[\"" << (*f_iter)->get_name() - << "\"] = Processor.process_" << (*f_iter)->get_name() << endl; + << "\"] = Processor.process_" << (*f_iter)->get_name() << '\n'; } - f_service_ << indent() << "self._on_message_begin = None" << endl; + f_service_ << indent() << "self._on_message_begin = None" << '\n'; indent_down(); - f_service_ << endl; + f_service_ << '\n'; - f_service_ << indent() << "def on_message_begin(self, func):" << endl; + f_service_ << indent() << "def on_message_begin(self, func):" << '\n'; indent_up(); - f_service_ << indent() << "self._on_message_begin = func" << endl; + f_service_ << indent() << "self._on_message_begin = func" << '\n'; indent_down(); - f_service_ << endl; + f_service_ << '\n'; // Generate the server implementation - f_service_ << indent() << "def process(self, iprot, oprot):" << endl; + f_service_ << indent() << "def process(self, iprot, oprot):" << '\n'; indent_up(); - f_service_ << indent() << "(name, type, seqid) = iprot.readMessageBegin()" << endl; - f_service_ << indent() << "if self._on_message_begin:" << endl; + f_service_ << indent() << "(name, type, seqid) = iprot.readMessageBegin()" << '\n'; + f_service_ << indent() << "if self._on_message_begin:" << '\n'; indent_up(); - f_service_ << indent() << "self._on_message_begin(name, type, seqid)" << endl; + f_service_ << indent() << "self._on_message_begin(name, type, seqid)" << '\n'; indent_down(); // TODO(mcslee): validate message // HOT: dictionary function lookup - f_service_ << indent() << "if name not in self._processMap:" << endl; + f_service_ << indent() << "if name not in self._processMap:" << '\n'; indent_up(); - f_service_ << indent() << "iprot.skip(TType.STRUCT)" << endl - << indent() << "iprot.readMessageEnd()" << endl + f_service_ << indent() << "iprot.skip(TType.STRUCT)" << '\n' + << indent() << "iprot.readMessageEnd()" << '\n' << indent() << "x = TApplicationException(TApplicationException.UNKNOWN_METHOD, 'Unknown " "function %s' % (name))" - << endl - << indent() << "oprot.writeMessageBegin(name, TMessageType.EXCEPTION, seqid)" << endl - << indent() << "x.write(oprot)" << endl - << indent() << "oprot.writeMessageEnd()" << endl - << indent() << "oprot.trans.flush()" << endl; + << '\n' + << indent() << "oprot.writeMessageBegin(name, TMessageType.EXCEPTION, seqid)" << '\n' + << indent() << "x.write(oprot)" << '\n' + << indent() << "oprot.writeMessageEnd()" << '\n' + << indent() << "oprot.trans.flush()" << '\n'; if (gen_twisted_) { - f_service_ << indent() << "return defer.succeed(None)" << endl; + f_service_ << indent() << "return defer.succeed(None)" << '\n'; } else { - f_service_ << indent() << "return" << endl; + f_service_ << indent() << "return" << '\n'; } indent_down(); - f_service_ << indent() << "else:" << endl; + f_service_ << indent() << "else:" << '\n'; if (gen_twisted_ || gen_tornado_) { f_service_ << indent() << indent_str() - << "return self._processMap[name](self, seqid, iprot, oprot)" << endl; + << "return self._processMap[name](self, seqid, iprot, oprot)" << '\n'; } else { f_service_ << indent() << indent_str() << "self._processMap[name](self, seqid, iprot, oprot)" - << endl; + << '\n'; // Read end of args field, the T_STOP, and the struct close - f_service_ << indent() << "return True" << endl; + f_service_ << indent() << "return True" << '\n'; } indent_down(); // Generate the process subfunctions for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { - f_service_ << endl; + f_service_ << '\n'; generate_process_function(tservice, *f_iter); } @@ -2022,11 +2046,11 @@ void t_py_generator::generate_process_function(t_service* tservice, t_function* (void)tservice; // Open function if (gen_tornado_) { - f_service_ << indent() << "@gen.coroutine" << endl << indent() << "def process_" - << tfunction->get_name() << "(self, seqid, iprot, oprot):" << endl; + f_service_ << indent() << "@gen.coroutine" << '\n' << indent() << "def process_" + << tfunction->get_name() << "(self, seqid, iprot, oprot):" << '\n'; } else { f_service_ << indent() << "def process_" << tfunction->get_name() - << "(self, seqid, iprot, oprot):" << endl; + << "(self, seqid, iprot, oprot):" << '\n'; } indent_up(); @@ -2034,8 +2058,8 @@ void t_py_generator::generate_process_function(t_service* tservice, t_function* string argsname = tfunction->get_name() + "_args"; string resultname = tfunction->get_name() + "_result"; - f_service_ << indent() << "args = " << argsname << "()" << endl << indent() << "args.read(iprot)" - << endl << indent() << "iprot.readMessageEnd()" << endl; + f_service_ << indent() << "args = " << argsname << "()" << '\n' << indent() << "args.read(iprot)" + << '\n' << indent() << "iprot.readMessageEnd()" << '\n'; t_struct* xs = tfunction->get_xceptions(); const std::vector& xceptions = xs->get_members(); @@ -2043,7 +2067,7 @@ void t_py_generator::generate_process_function(t_service* tservice, t_function* // Declare result for non oneway function if (!tfunction->is_oneway()) { - f_service_ << indent() << "result = " << resultname << "()" << endl; + f_service_ << indent() << "result = " << resultname << "()" << '\n'; } if (gen_twisted_) { @@ -2063,85 +2087,85 @@ void t_py_generator::generate_process_function(t_service* tservice, t_function* } f_service_ << "args." << (*f_iter)->get_name(); } - f_service_ << ")" << endl; + f_service_ << ")" << '\n'; if (tfunction->is_oneway()) { f_service_ << indent() << "d.addErrback(self.handle_exception_" << tfunction->get_name() - << ", seqid)" << endl; + << ", seqid)" << '\n'; } else { f_service_ << indent() << "d.addCallback(self.write_results_success_" << tfunction->get_name() - << ", result, seqid, oprot)" << endl + << ", result, seqid, oprot)" << '\n' << indent() << "d.addErrback(self.write_results_exception_" - << tfunction->get_name() << ", result, seqid, oprot)" << endl; + << tfunction->get_name() << ", result, seqid, oprot)" << '\n'; } - f_service_ << indent() << "return d" << endl << endl; + f_service_ << indent() << "return d" << '\n' << '\n'; indent_down(); if (tfunction->is_oneway()) { indent(f_service_) << "def handle_exception_" << tfunction->get_name() - << "(self, error, seqid):" << endl; + << "(self, error, seqid):" << '\n'; } else { indent(f_service_) << "def write_results_success_" << tfunction->get_name() - << "(self, success, result, seqid, oprot):" << endl; + << "(self, success, result, seqid, oprot):" << '\n'; indent_up(); if (!tfunction->get_returntype()->is_void()) { - f_service_ << indent() << "result.success = success" << endl; + f_service_ << indent() << "result.success = success" << '\n'; } f_service_ << indent() << "oprot.writeMessageBegin(\"" << tfunction->get_name() - << "\", TMessageType.REPLY, seqid)" << endl - << indent() << "result.write(oprot)" << endl - << indent() << "oprot.writeMessageEnd()" << endl - << indent() << "oprot.trans.flush()" << endl - << endl; + << "\", TMessageType.REPLY, seqid)" << '\n' + << indent() << "result.write(oprot)" << '\n' + << indent() << "oprot.writeMessageEnd()" << '\n' + << indent() << "oprot.trans.flush()" << '\n' + << '\n'; indent_down(); indent(f_service_) << "def write_results_exception_" << tfunction->get_name() - << "(self, error, result, seqid, oprot):" << endl; + << "(self, error, result, seqid, oprot):" << '\n'; } indent_up(); if (!tfunction->is_oneway()) { - f_service_ << indent() << "msg_type = TMessageType.REPLY" << endl; + f_service_ << indent() << "msg_type = TMessageType.REPLY" << '\n'; } - f_service_ << indent() << "try:" << endl; + f_service_ << indent() << "try:" << '\n'; // Kinda absurd - f_service_ << indent() << indent_str() << "error.raiseException()" << endl; + f_service_ << indent() << indent_str() << "error.raiseException()" << '\n'; if (!tfunction->is_oneway()) { for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { const string& xname = (*x_iter)->get_name(); f_service_ << indent() << "except " << type_name((*x_iter)->get_type()) << " as " << xname - << ":" << endl; + << ":" << '\n'; indent_up(); - f_service_ << indent() << "result." << xname << " = " << xname << endl; + f_service_ << indent() << "result." << xname << " = " << xname << '\n'; indent_down(); } } - f_service_ << indent() << "except TTransport.TTransportException:" << endl - << indent() << indent_str() << "raise" << endl; + f_service_ << indent() << "except TTransport.TTransportException:" << '\n' + << indent() << indent_str() << "raise" << '\n'; if (!tfunction->is_oneway()) { - f_service_ << indent() << "except TApplicationException as ex:" << endl + f_service_ << indent() << "except TApplicationException as ex:" << '\n' << indent() << indent_str() - << "logging.exception('TApplication exception in handler')" << endl - << indent() << indent_str() << "msg_type = TMessageType.EXCEPTION" << endl - << indent() << indent_str() << "result = ex" << endl - << indent() << "except Exception:" << endl + << "logging.exception('TApplication exception in handler')" << '\n' + << indent() << indent_str() << "msg_type = TMessageType.EXCEPTION" << '\n' + << indent() << indent_str() << "result = ex" << '\n' + << indent() << "except Exception:" << '\n' << indent() << indent_str() - << "logging.exception('Unexpected exception in handler')" << endl - << indent() << indent_str() << "msg_type = TMessageType.EXCEPTION" << endl + << "logging.exception('Unexpected exception in handler')" << '\n' + << indent() << indent_str() << "msg_type = TMessageType.EXCEPTION" << '\n' << indent() << indent_str() << "result = TApplicationException(TApplicationException.INTERNAL_ERROR, " "'Internal error')" - << endl + << '\n' << indent() << "oprot.writeMessageBegin(\"" << tfunction->get_name() - << "\", msg_type, seqid)" << endl - << indent() << "result.write(oprot)" << endl - << indent() << "oprot.writeMessageEnd()" << endl - << indent() << "oprot.trans.flush()" << endl; + << "\", msg_type, seqid)" << '\n' + << indent() << "result.write(oprot)" << '\n' + << indent() << "oprot.writeMessageEnd()" << '\n' + << indent() << "oprot.trans.flush()" << '\n'; } else { - f_service_ << indent() << "except Exception:" << endl + f_service_ << indent() << "except Exception:" << '\n' << indent() << indent_str() - << "logging.exception('Exception in oneway handler')" << endl; + << "logging.exception('Exception in oneway handler')" << '\n'; } indent_down(); @@ -2152,9 +2176,9 @@ void t_py_generator::generate_process_function(t_service* tservice, t_function* vector::const_iterator f_iter; if (!tfunction->is_oneway()) { - indent(f_service_) << "msg_type = TMessageType.REPLY" << endl; + indent(f_service_) << "msg_type = TMessageType.REPLY" << '\n'; } - f_service_ << indent() << "try:" << endl; + f_service_ << indent() << "try:" << '\n'; indent_up(); f_service_ << indent(); if (!tfunction->is_oneway() && !tfunction->get_returntype()->is_void()) { @@ -2170,45 +2194,45 @@ void t_py_generator::generate_process_function(t_service* tservice, t_function* } f_service_ << "args." << (*f_iter)->get_name(); } - f_service_ << "))" << endl; + f_service_ << "))" << '\n'; indent_down(); if (!tfunction->is_oneway()) { for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { const string& xname = (*x_iter)->get_name(); f_service_ << indent() << "except " << type_name((*x_iter)->get_type()) << " as " << xname - << ":" << endl - << indent() << indent_str() << "result." << xname << " = " << xname << endl; + << ":" << '\n' + << indent() << indent_str() << "result." << xname << " = " << xname << '\n'; } } - f_service_ << indent() << "except TTransport.TTransportException:" << endl - << indent() << indent_str() << "raise" << endl; + f_service_ << indent() << "except TTransport.TTransportException:" << '\n' + << indent() << indent_str() << "raise" << '\n'; if (!tfunction->is_oneway()) { - f_service_ << indent() << "except TApplicationException as ex:" << endl + f_service_ << indent() << "except TApplicationException as ex:" << '\n' << indent() << indent_str() - << "logging.exception('TApplication exception in handler')" << endl - << indent() << indent_str() << "msg_type = TMessageType.EXCEPTION" << endl - << indent() << indent_str() << "result = ex" << endl - << indent() << "except Exception:" << endl + << "logging.exception('TApplication exception in handler')" << '\n' + << indent() << indent_str() << "msg_type = TMessageType.EXCEPTION" << '\n' + << indent() << indent_str() << "result = ex" << '\n' + << indent() << "except Exception:" << '\n' << indent() << indent_str() - << "logging.exception('Unexpected exception in handler')" << endl - << indent() << indent_str() << "msg_type = TMessageType.EXCEPTION" << endl + << "logging.exception('Unexpected exception in handler')" << '\n' + << indent() << indent_str() << "msg_type = TMessageType.EXCEPTION" << '\n' << indent() << indent_str() << "result = TApplicationException(TApplicationException.INTERNAL_ERROR, " "'Internal error')" - << endl; + << '\n'; } else { - f_service_ << indent() << "except Exception:" << endl + f_service_ << indent() << "except Exception:" << '\n' << indent() << indent_str() - << "logging.exception('Exception in oneway handler')" << endl; + << "logging.exception('Exception in oneway handler')" << '\n'; } if (!tfunction->is_oneway()) { f_service_ << indent() << "oprot.writeMessageBegin(\"" << tfunction->get_name() - << "\", msg_type, seqid)" << endl - << indent() << "result.write(oprot)" << endl - << indent() << "oprot.writeMessageEnd()" << endl - << indent() << "oprot.trans.flush()" << endl; + << "\", msg_type, seqid)" << '\n' + << indent() << "result.write(oprot)" << '\n' + << indent() << "oprot.writeMessageEnd()" << '\n' + << indent() << "oprot.trans.flush()" << '\n'; } // Close function @@ -2217,7 +2241,7 @@ void t_py_generator::generate_process_function(t_service* tservice, t_function* } else { // py // Try block for a function with exceptions // It also catches arbitrary exceptions raised by handler method to propagate them to the client - f_service_ << indent() << "try:" << endl; + f_service_ << indent() << "try:" << '\n'; indent_up(); // Generate the function call @@ -2239,48 +2263,48 @@ void t_py_generator::generate_process_function(t_service* tservice, t_function* } f_service_ << "args." << (*f_iter)->get_name(); } - f_service_ << ")" << endl; + f_service_ << ")" << '\n'; if (!tfunction->is_oneway()) { - f_service_ << indent() << "msg_type = TMessageType.REPLY" << endl; + f_service_ << indent() << "msg_type = TMessageType.REPLY" << '\n'; } indent_down(); f_service_ << indent() - << "except TTransport.TTransportException:" << endl - << indent() << indent_str() << "raise" << endl; + << "except TTransport.TTransportException:" << '\n' + << indent() << indent_str() << "raise" << '\n'; if (!tfunction->is_oneway()) { for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { const string& xname = (*x_iter)->get_name(); f_service_ << indent() << "except " << type_name((*x_iter)->get_type()) << " as " << xname - << ":" << endl; + << ":" << '\n'; indent_up(); - f_service_ << indent() << "msg_type = TMessageType.REPLY" << endl; - f_service_ << indent() << "result." << xname << " = " << xname << endl; + f_service_ << indent() << "msg_type = TMessageType.REPLY" << '\n'; + f_service_ << indent() << "result." << xname << " = " << xname << '\n'; indent_down(); } - f_service_ << indent() << "except TApplicationException as ex:" << endl + f_service_ << indent() << "except TApplicationException as ex:" << '\n' << indent() << indent_str() - << "logging.exception('TApplication exception in handler')" << endl - << indent() << indent_str() << "msg_type = TMessageType.EXCEPTION" << endl - << indent() << indent_str() << "result = ex" << endl - << indent() << "except Exception:" << endl + << "logging.exception('TApplication exception in handler')" << '\n' + << indent() << indent_str() << "msg_type = TMessageType.EXCEPTION" << '\n' + << indent() << indent_str() << "result = ex" << '\n' + << indent() << "except Exception:" << '\n' << indent() << indent_str() - << "logging.exception('Unexpected exception in handler')" << endl - << indent() << indent_str() << "msg_type = TMessageType.EXCEPTION" << endl + << "logging.exception('Unexpected exception in handler')" << '\n' + << indent() << indent_str() << "msg_type = TMessageType.EXCEPTION" << '\n' << indent() << indent_str() << "result = TApplicationException(TApplicationException.INTERNAL_ERROR, " "'Internal error')" - << endl + << '\n' << indent() << "oprot.writeMessageBegin(\"" << tfunction->get_name() - << "\", msg_type, seqid)" << endl - << indent() << "result.write(oprot)" << endl - << indent() << "oprot.writeMessageEnd()" << endl - << indent() << "oprot.trans.flush()" << endl; + << "\", msg_type, seqid)" << '\n' + << indent() << "result.write(oprot)" << '\n' + << indent() << "oprot.writeMessageEnd()" << '\n' + << indent() << "oprot.trans.flush()" << '\n'; } else { - f_service_ << indent() << "except Exception:" << endl - << indent() << indent_str() << "logging.exception('Exception in oneway handler')" << endl; + f_service_ << indent() << "except Exception:" << '\n' + << indent() << indent_str() << "logging.exception('Exception in oneway handler')" << '\n'; } // Close function @@ -2341,18 +2365,21 @@ void t_py_generator::generate_deserialize_field(ostream& out, case t_base_type::TYPE_DOUBLE: out << "readDouble()"; break; + case t_base_type::TYPE_UUID: + out << "readUuid()"; + break; default: throw "compiler error: no Python name for base type " + t_base_type::t_base_name(tbase); } } - out << endl; + out << '\n'; } else if (type->is_enum()) { if (gen_enum_) { indent(out) << name << " = " << type_name(type) << "(iprot.readI32())"; } else { indent(out) << name << " = iprot.readI32()"; } - out << endl; + out << '\n'; } else { printf("DO NOT KNOW HOW TO DESERIALIZE FIELD '%s' TYPE '%s'\n", tfield->get_name().c_str(), @@ -2365,10 +2392,10 @@ void t_py_generator::generate_deserialize_field(ostream& out, */ void t_py_generator::generate_deserialize_struct(ostream& out, t_struct* tstruct, string prefix) { if (is_immutable(tstruct)) { - out << indent() << prefix << " = " << type_name(tstruct) << ".read(iprot)" << endl; + out << indent() << prefix << " = " << type_name(tstruct) << ".read(iprot)" << '\n'; } else { - out << indent() << prefix << " = " << type_name(tstruct) << "()" << endl - << indent() << prefix << ".read(iprot)" << endl; + out << indent() << prefix << " = " << type_name(tstruct) << "()" << '\n' + << indent() << prefix << ".read(iprot)" << '\n'; } } @@ -2389,20 +2416,20 @@ void t_py_generator::generate_deserialize_container(ostream& out, t_type* ttype, // Declare variables, read header if (ttype->is_map()) { - out << indent() << prefix << " = {}" << endl << indent() << "(" << ktype << ", " << vtype - << ", " << size << ") = iprot.readMapBegin()" << endl; + out << indent() << prefix << " = {}" << '\n' << indent() << "(" << ktype << ", " << vtype + << ", " << size << ") = iprot.readMapBegin()" << '\n'; } else if (ttype->is_set()) { - out << indent() << prefix << " = set()" << endl << indent() << "(" << etype << ", " << size - << ") = iprot.readSetBegin()" << endl; + out << indent() << prefix << " = set()" << '\n' << indent() << "(" << etype << ", " << size + << ") = iprot.readSetBegin()" << '\n'; } else if (ttype->is_list()) { - out << indent() << prefix << " = []" << endl << indent() << "(" << etype << ", " << size - << ") = iprot.readListBegin()" << endl; + out << indent() << prefix << " = []" << '\n' << indent() << "(" << etype << ", " << size + << ") = iprot.readListBegin()" << '\n'; } // For loop iterates over elements string i = tmp("_i"); indent(out) << - "for " << i << " in range(" << size << "):" << endl; + "for " << i << " in range(" << size << "):" << '\n'; indent_up(); @@ -2418,20 +2445,20 @@ void t_py_generator::generate_deserialize_container(ostream& out, t_type* ttype, // Read container end if (ttype->is_map()) { - indent(out) << "iprot.readMapEnd()" << endl; + indent(out) << "iprot.readMapEnd()" << '\n'; if (is_immutable(ttype)) { - indent(out) << prefix << " = TFrozenDict(" << prefix << ")" << endl; + indent(out) << prefix << " = TFrozenDict(" << prefix << ")" << '\n'; } } else if (ttype->is_set()) { - indent(out) << "iprot.readSetEnd()" << endl; + indent(out) << "iprot.readSetEnd()" << '\n'; if (is_immutable(ttype)) { - indent(out) << prefix << " = frozenset(" << prefix << ")" << endl; + indent(out) << prefix << " = frozenset(" << prefix << ")" << '\n'; } } else if (ttype->is_list()) { if (is_immutable(ttype)) { - indent(out) << prefix << " = tuple(" << prefix << ")" << endl; + indent(out) << prefix << " = tuple(" << prefix << ")" << '\n'; } - indent(out) << "iprot.readListEnd()" << endl; + indent(out) << "iprot.readListEnd()" << '\n'; } } @@ -2447,7 +2474,7 @@ void t_py_generator::generate_deserialize_map_element(ostream& out, t_map* tmap, generate_deserialize_field(out, &fkey); generate_deserialize_field(out, &fval); - indent(out) << prefix << "[" << key << "] = " << val << endl; + indent(out) << prefix << "[" << key << "] = " << val << '\n'; } /** @@ -2459,7 +2486,7 @@ void t_py_generator::generate_deserialize_set_element(ostream& out, t_set* tset, generate_deserialize_field(out, &felem); - indent(out) << prefix << ".add(" << elem << ")" << endl; + indent(out) << prefix << ".add(" << elem << ")" << '\n'; } /** @@ -2473,7 +2500,7 @@ void t_py_generator::generate_deserialize_list_element(ostream& out, generate_deserialize_field(out, &felem); - indent(out) << prefix << ".append(" << elem << ")" << endl; + indent(out) << prefix << ".append(" << elem << ")" << '\n'; } /** @@ -2533,6 +2560,9 @@ void t_py_generator::generate_serialize_field(ostream& out, t_field* tfield, str case t_base_type::TYPE_DOUBLE: out << "writeDouble(" << name << ")"; break; + case t_base_type::TYPE_UUID: + out << "writeUuid(" << name << ")"; + break; default: throw "compiler error: no Python name for base type " + t_base_type::t_base_name(tbase); } @@ -2543,7 +2573,7 @@ void t_py_generator::generate_serialize_field(ostream& out, t_field* tfield, str out << "writeI32(" << name << ")"; } } - out << endl; + out << '\n'; } else { printf("DO NOT KNOW HOW TO SERIALIZE FIELD '%s%s' TYPE '%s'\n", prefix.c_str(), @@ -2560,50 +2590,50 @@ void t_py_generator::generate_serialize_field(ostream& out, t_field* tfield, str */ void t_py_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix) { (void)tstruct; - indent(out) << prefix << ".write(oprot)" << endl; + indent(out) << prefix << ".write(oprot)" << '\n'; } void t_py_generator::generate_serialize_container(ostream& out, t_type* ttype, string prefix) { if (ttype->is_map()) { indent(out) << "oprot.writeMapBegin(" << type_to_enum(((t_map*)ttype)->get_key_type()) << ", " << type_to_enum(((t_map*)ttype)->get_val_type()) << ", " - << "len(" << prefix << "))" << endl; + << "len(" << prefix << "))" << '\n'; } else if (ttype->is_set()) { indent(out) << "oprot.writeSetBegin(" << type_to_enum(((t_set*)ttype)->get_elem_type()) << ", " - << "len(" << prefix << "))" << endl; + << "len(" << prefix << "))" << '\n'; } else if (ttype->is_list()) { indent(out) << "oprot.writeListBegin(" << type_to_enum(((t_list*)ttype)->get_elem_type()) << ", " - << "len(" << prefix << "))" << endl; + << "len(" << prefix << "))" << '\n'; } if (ttype->is_map()) { string kiter = tmp("kiter"); string viter = tmp("viter"); - indent(out) << "for " << kiter << ", " << viter << " in " << prefix << ".items():" << endl; + indent(out) << "for " << kiter << ", " << viter << " in " << prefix << ".items():" << '\n'; indent_up(); generate_serialize_map_element(out, (t_map*)ttype, kiter, viter); indent_down(); } else if (ttype->is_set()) { string iter = tmp("iter"); - indent(out) << "for " << iter << " in " << prefix << ":" << endl; + indent(out) << "for " << iter << " in " << prefix << ":" << '\n'; indent_up(); generate_serialize_set_element(out, (t_set*)ttype, iter); indent_down(); } else if (ttype->is_list()) { string iter = tmp("iter"); - indent(out) << "for " << iter << " in " << prefix << ":" << endl; + indent(out) << "for " << iter << " in " << prefix << ":" << '\n'; indent_up(); generate_serialize_list_element(out, (t_list*)ttype, iter); indent_down(); } if (ttype->is_map()) { - indent(out) << "oprot.writeMapEnd()" << endl; + indent(out) << "oprot.writeMapEnd()" << '\n'; } else if (ttype->is_set()) { - indent(out) << "oprot.writeSetEnd()" << endl; + indent(out) << "oprot.writeSetEnd()" << '\n'; } else if (ttype->is_list()) { - indent(out) << "oprot.writeListEnd()" << endl; + indent(out) << "oprot.writeListEnd()" << '\n'; } } @@ -2669,7 +2699,7 @@ void t_py_generator::generate_python_docstring(ostream& out, const vector& fields = tstruct->get_members(); if (fields.size() > 0) { if (has_doc) { - ss << endl; + ss << '\n'; } has_doc = true; ss << subheader << ":\n"; @@ -2680,7 +2710,7 @@ void t_py_generator::generate_python_docstring(ostream& out, if (p->has_doc()) { ss << ": " << p->get_doc(); } else { - ss << endl; + ss << '\n'; } } } @@ -2706,7 +2736,10 @@ void t_py_generator::generate_python_docstring(ostream& out, t_doc* tdoc) { */ string t_py_generator::declare_argument(t_field* tfield) { std::ostringstream result; - result << tfield->get_name() << "="; + t_field::e_req req = tfield->get_req(); + result << tfield->get_name() << member_hint(tfield->get_type(), req); + + result << " = "; if (tfield->get_value() != nullptr) { result << render_field_default_value(tfield); } else { @@ -2735,7 +2768,7 @@ string t_py_generator::render_field_default_value(t_field* tfield) { * @param tfunction Function definition * @return String of rendered function definition */ -string t_py_generator::function_signature(t_function* tfunction, bool interface) { +string t_py_generator::function_signature(t_function* tfunction, bool interface, bool send_part) { vector pre; vector post; string signature = tfunction->get_name() + "("; @@ -2745,6 +2778,10 @@ string t_py_generator::function_signature(t_function* tfunction, bool interface) } signature += argument_list(tfunction->get_arglist(), &pre, &post) + ")"; + if (!send_part) { + signature += func_hint(tfunction->get_returntype()); + } + return signature; } @@ -2775,6 +2812,7 @@ string t_py_generator::argument_list(t_struct* tstruct, vector* pre, vec result += ", "; } result += (*f_iter)->get_name(); + result += arg_hint((*f_iter)->get_type()); } if (post) { for (s_iter = post->begin(); s_iter != post->end(); ++s_iter) { @@ -2804,8 +2842,78 @@ string t_py_generator::type_name(t_type* ttype) { return ttype->get_name(); } +string t_py_generator::arg_hint(t_type* type) { + if (gen_type_hints_) { + return ": " + type_to_py_type(type); + } + + return ""; +} + +string t_py_generator::member_hint(t_type* type, t_field::e_req req) { + if (gen_type_hints_) { + if (req != t_field::T_REQUIRED) { + return ": typing.Optional[" + type_to_py_type(type) + "]"; + } else { + return ": " + type_to_py_type(type); + } + } + + return ""; +} + +string t_py_generator::func_hint(t_type* type) { + if (gen_type_hints_) { + return " -> " + type_to_py_type(type); + } + + return ""; +} + +/** + * Converts the parse type to a Python type + */ +string t_py_generator::type_to_py_type(t_type* type) { + type = get_true_type(type); + + if (type->is_binary()) { + return "bytes"; + } + 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: + return "None"; + case t_base_type::TYPE_STRING: + return "str"; + case t_base_type::TYPE_BOOL: + return "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: + return "int"; + case t_base_type::TYPE_DOUBLE: + return "float"; + case t_base_type::TYPE_UUID: + return "UUID"; + } + } else if (type->is_enum() || type->is_struct() || type->is_xception()) { + return type_name(type); + } else if (type->is_map()) { + return "dict[" + type_to_py_type(((t_map*)type)->get_key_type()) + ", " + + type_to_py_type(((t_map*)type)->get_val_type()) + "]"; + } else if (type->is_set()) { + return "set[" + type_to_py_type(((t_set*)type)->get_elem_type()) + "]"; + } else if (type->is_list()) { + return "list[" + type_to_py_type(((t_list*)type)->get_elem_type()) + "]"; + } + + throw "INVALID TYPE IN type_to_py_type: " + type->get_name(); +} + /** - * Converts the parse type to a Python tyoe + * Converts the parse type to a Python type enum */ string t_py_generator::type_to_enum(t_type* type) { type = get_true_type(type); @@ -2829,6 +2937,8 @@ string t_py_generator::type_to_enum(t_type* type) { return "TType.I64"; case t_base_type::TYPE_DOUBLE: return "TType.DOUBLE"; + case t_base_type::TYPE_UUID: + return "TType.UUID"; default: throw "compiler error: unhandled type"; } @@ -2887,7 +2997,6 @@ std::string t_py_generator::display_name() const { return "Python"; } - THRIFT_REGISTER_GENERATOR( py, "Python", @@ -2908,4 +3017,5 @@ THRIFT_REGISTER_GENERATOR( " Package prefix for generated files.\n" " old_style: Deprecated. Generate old-style classes.\n" " enum: Generates Python's IntEnum, connects thrift to python enums. Python 3.4 and higher.\n" + " type_hints: Generate type hints and type checks in write method. Requires the enum option.\n" ) diff --git a/compiler/cpp/src/thrift/generate/t_rb_generator.cc b/compiler/cpp/src/thrift/generate/t_rb_generator.cc index 17e57cf95df..e9465736692 100644 --- a/compiler/cpp/src/thrift/generate/t_rb_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_rb_generator.cc @@ -43,8 +43,6 @@ using std::string; using std::stringstream; using std::vector; -static const string endl = "\n"; // avoid ostream << std::endl flushes - /** * A subclass of std::ofstream that includes indenting functionality. */ @@ -283,11 +281,11 @@ void t_rb_generator::init_generator() { f_consts_.open(f_consts_name.c_str()); // Print header - f_types_ << rb_autogen_comment() << endl << render_require_thrift() << render_includes() << endl; + f_types_ << rb_autogen_comment() << '\n' << render_require_thrift() << render_includes() << '\n'; begin_namespace(f_types_, ruby_modules(program_)); - f_consts_ << rb_autogen_comment() << endl << render_require_thrift() << "require '" - << require_prefix_ << underscore(program_name_) << "_types'" << endl << endl; + f_consts_ << rb_autogen_comment() << '\n' << render_require_thrift() << "require '" + << require_prefix_ << underscore(program_name_) << "_types'" << '\n' << '\n'; begin_namespace(f_consts_, ruby_modules(program_)); } @@ -360,7 +358,7 @@ void t_rb_generator::generate_typedef(t_typedef* ttypedef) { * @param tenum The enumeration */ void t_rb_generator::generate_enum(t_enum* tenum) { - f_types_.indent() << "module " << capitalize(tenum->get_name()) << endl; + f_types_.indent() << "module " << capitalize(tenum->get_name()) << '\n'; f_types_.indent_up(); vector constants = tenum->get_constants(); @@ -374,7 +372,7 @@ void t_rb_generator::generate_enum(t_enum* tenum) { string name = capitalize((*c_iter)->get_name()); generate_rdoc(f_types_, *c_iter); - f_types_.indent() << name << " = " << value << endl; + f_types_.indent() << name << " = " << value << '\n'; } // Create a hash mapping values back to their names (as strings) since ruby has no native enum @@ -387,7 +385,7 @@ void t_rb_generator::generate_enum(t_enum* tenum) { f_types_ << ", "; f_types_ << value << " => \"" << capitalize((*c_iter)->get_name()) << "\""; } - f_types_ << "}" << endl; + f_types_ << "}" << '\n'; // Create a set with valid values for this enum f_types_.indent() << "VALID_VALUES = Set.new(["; @@ -397,10 +395,10 @@ void t_rb_generator::generate_enum(t_enum* tenum) { f_types_ << ", "; f_types_ << capitalize((*c_iter)->get_name()); } - f_types_ << "]).freeze" << endl; + f_types_ << "]).freeze" << '\n'; f_types_.indent_down(); - f_types_.indent() << "end" << endl << endl; + f_types_.indent() << "end" << '\n' << '\n'; } /** @@ -414,7 +412,7 @@ void t_rb_generator::generate_const(t_const* tconst) { name[0] = toupper(name[0]); f_consts_.indent() << name << " = "; - render_const_value(f_consts_, type, value) << endl << endl; + render_const_value(f_consts_, type, value) << '\n' << '\n'; } /** @@ -454,7 +452,7 @@ t_rb_ofstream& t_rb_generator::render_const_value(t_rb_ofstream& out, } else if (type->is_enum()) { out.indent() << value->get_integer(); } else if (type->is_struct() || type->is_xception()) { - out << full_type_name(type) << ".new({" << endl; + out << full_type_name(type) << ".new({" << '\n'; out.indent_up(); const vector& fields = ((t_struct*)type)->get_members(); vector::const_iterator f_iter; @@ -472,21 +470,21 @@ t_rb_ofstream& t_rb_generator::render_const_value(t_rb_ofstream& out, } out.indent(); render_const_value(out, g_type_string, v_iter->first) << " => "; - render_const_value(out, field_type, v_iter->second) << "," << endl; + render_const_value(out, field_type, v_iter->second) << "," << '\n'; } out.indent_down(); out.indent() << "})"; } else if (type->is_map()) { t_type* ktype = ((t_map*)type)->get_key_type(); t_type* vtype = ((t_map*)type)->get_val_type(); - out << "{" << endl; + out << "{" << '\n'; out.indent_up(); const map& val = value->get_map(); map::const_iterator v_iter; for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { out.indent(); render_const_value(out, ktype, v_iter->first) << " => "; - render_const_value(out, vtype, v_iter->second) << "," << endl; + render_const_value(out, vtype, v_iter->second) << "," << '\n'; } out.indent_down(); out.indent() << "}"; @@ -498,16 +496,16 @@ t_rb_ofstream& t_rb_generator::render_const_value(t_rb_ofstream& out, etype = ((t_set*)type)->get_elem_type(); } if (type->is_set()) { - out << "Set.new([" << endl; + out << "Set.new([" << '\n'; } else { - out << "[" << endl; + out << "[" << '\n'; } out.indent_up(); const vector& val = value->get_list(); vector::const_iterator v_iter; for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { out.indent(); - render_const_value(out, etype, *v_iter) << "," << endl; + render_const_value(out, etype, *v_iter) << "," << '\n'; } out.indent_down(); if (type->is_set()) { @@ -552,7 +550,7 @@ void t_rb_generator::generate_rb_struct_declaration(t_rb_ofstream& out, t_struct if (is_exception) { out << " < ::Thrift::Exception"; } - out << "; end" << endl << endl; + out << "; end" << '\n' << '\n'; } /** @@ -576,10 +574,10 @@ void t_rb_generator::generate_rb_struct(t_rb_ofstream& out, if (is_exception) { out << " < ::Thrift::Exception"; } - out << endl; + out << '\n'; out.indent_up(); - out.indent() << "include ::Thrift::Struct, ::Thrift::Struct_Union" << endl; + out.indent() << "include ::Thrift::Struct, ::Thrift::Struct_Union" << '\n'; if (is_exception) { generate_rb_simple_exception_constructor(out, tstruct); @@ -589,10 +587,10 @@ void t_rb_generator::generate_rb_struct(t_rb_ofstream& out, generate_field_defns(out, tstruct); generate_rb_struct_required_validator(out, tstruct); - out.indent() << "::Thrift::Struct.generate_accessors self" << endl; + out.indent() << "::Thrift::Struct.generate_accessors self" << '\n'; out.indent_down(); - out.indent() << "end" << endl << endl; + out.indent() << "end" << '\n' << '\n'; } /** @@ -603,10 +601,10 @@ void t_rb_generator::generate_rb_union(t_rb_ofstream& out, bool is_exception = false) { (void)is_exception; generate_rdoc(out, tstruct); - out.indent() << "class " << type_name(tstruct) << " < ::Thrift::Union" << endl; + out.indent() << "class " << type_name(tstruct) << " < ::Thrift::Union" << '\n'; out.indent_up(); - out.indent() << "include ::Thrift::Struct_Union" << endl; + out.indent() << "include ::Thrift::Struct_Union" << '\n'; generate_field_constructors(out, tstruct); @@ -614,15 +612,15 @@ void t_rb_generator::generate_rb_union(t_rb_ofstream& out, generate_field_defns(out, tstruct); generate_rb_union_validator(out, tstruct); - out.indent() << "::Thrift::Union.generate_accessors self" << endl; + out.indent() << "::Thrift::Union.generate_accessors self" << '\n'; out.indent_down(); - out.indent() << "end" << endl << endl; + out.indent() << "end" << '\n' << '\n'; } void t_rb_generator::generate_field_constructors(t_rb_ofstream& out, t_struct* tstruct) { - out.indent() << "class << self" << endl; + out.indent() << "class << self" << '\n'; out.indent_up(); const vector& fields = tstruct->get_members(); @@ -630,19 +628,19 @@ void t_rb_generator::generate_field_constructors(t_rb_ofstream& out, t_struct* t for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if (f_iter != fields.begin()) { - out << endl; + out << '\n'; } std::string field_name = (*f_iter)->get_name(); - out.indent() << "def " << field_name << "(val)" << endl; - out.indent() << " " << tstruct->get_name() << ".new(:" << field_name << ", val)" << endl; - out.indent() << "end" << endl; + out.indent() << "def " << field_name << "(val)" << '\n'; + out.indent() << " " << tstruct->get_name() << ".new(:" << field_name << ", val)" << '\n'; + out.indent() << "end" << '\n'; } out.indent_down(); - out.indent() << "end" << endl; + out.indent() << "end" << '\n'; - out << endl; + out << '\n'; } void t_rb_generator::generate_rb_simple_exception_constructor(t_rb_ofstream& out, @@ -655,15 +653,15 @@ void t_rb_generator::generate_rb_simple_exception_constructor(t_rb_ofstream& out if ((*m_iter)->get_type()->is_string()) { string name = (*m_iter)->get_name(); - out.indent() << "def initialize(message=nil)" << endl; + out.indent() << "def initialize(message=nil)" << '\n'; out.indent_up(); - out.indent() << "super()" << endl; - out.indent() << "self." << name << " = message" << endl; + out.indent() << "super()" << '\n'; + out.indent() << "self." << name << " = message" << '\n'; out.indent_down(); - out.indent() << "end" << endl << endl; + out.indent() << "end" << '\n' << '\n'; if (name != "message") { - out.indent() << "def message; " << name << " end" << endl << endl; + out.indent() << "def message; " << name << " end" << '\n' << '\n'; } } } @@ -677,20 +675,20 @@ void t_rb_generator::generate_field_constants(t_rb_ofstream& out, t_struct* tstr std::string field_name = (*f_iter)->get_name(); std::string cap_field_name = upcase_string(field_name); - out.indent() << cap_field_name << " = " << (*f_iter)->get_key() << endl; + out.indent() << cap_field_name << " = " << (*f_iter)->get_key() << '\n'; } - out << endl; + out << '\n'; } void t_rb_generator::generate_field_defns(t_rb_ofstream& out, t_struct* tstruct) { const vector& fields = tstruct->get_members(); vector::const_iterator f_iter; - out.indent() << "FIELDS = {" << endl; + out.indent() << "FIELDS = {" << '\n'; out.indent_up(); for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if (f_iter != fields.begin()) { - out << "," << endl; + out << "," << '\n'; } // generate the field docstrings within the FIELDS constant. no real better place... @@ -705,10 +703,10 @@ void t_rb_generator::generate_field_defns(t_rb_ofstream& out, t_struct* tstruct) (*f_iter)->get_req() == t_field::T_OPTIONAL); } out.indent_down(); - out << endl; - out.indent() << "}" << endl << endl; + out << '\n'; + out.indent() << "}" << '\n' << '\n'; - out.indent() << "def struct_fields; FIELDS; end" << endl << endl; + out.indent() << "def struct_fields; FIELDS; end" << '\n' << '\n'; } void t_rb_generator::generate_field_data(t_rb_ofstream& out, @@ -765,7 +763,7 @@ void t_rb_generator::generate_field_data(t_rb_ofstream& out, void t_rb_generator::begin_namespace(t_rb_ofstream& out, vector modules) { for (auto & module : modules) { - out.indent() << "module " << module << endl; + out.indent() << "module " << module << '\n'; out.indent_up(); } } @@ -774,7 +772,7 @@ void t_rb_generator::end_namespace(t_rb_ofstream& out, vector modul for (vector::reverse_iterator m_iter = modules.rbegin(); m_iter != modules.rend(); ++m_iter) { out.indent_down(); - out.indent() << "end" << endl; + out.indent() << "end" << '\n'; } } @@ -787,25 +785,25 @@ void t_rb_generator::generate_service(t_service* tservice) { string f_service_name = namespace_dir_ + underscore(service_name_) + ".rb"; f_service_.open(f_service_name.c_str()); - f_service_ << rb_autogen_comment() << endl << render_require_thrift(); + f_service_ << rb_autogen_comment() << '\n' << render_require_thrift(); if (tservice->get_extends() != nullptr) { if (namespaced_) { f_service_ << "require '" << rb_namespace_to_path_prefix( tservice->get_extends()->get_program()->get_namespace("rb")) - << underscore(tservice->get_extends()->get_name()) << "'" << endl; + << underscore(tservice->get_extends()->get_name()) << "'" << '\n'; } else { f_service_ << "require '" << require_prefix_ - << underscore(tservice->get_extends()->get_name()) << "'" << endl; + << underscore(tservice->get_extends()->get_name()) << "'" << '\n'; } } - f_service_ << "require '" << require_prefix_ << underscore(program_name_) << "_types'" << endl - << endl; + f_service_ << "require '" << require_prefix_ << underscore(program_name_) << "_types'" << '\n' + << '\n'; begin_namespace(f_service_, ruby_modules(tservice->get_program())); - f_service_.indent() << "module " << capitalize(tservice->get_name()) << endl; + f_service_.indent() << "module " << capitalize(tservice->get_name()) << '\n'; f_service_.indent_up(); // Generate the three main parts of the service (well, two for now in PHP) @@ -814,7 +812,7 @@ void t_rb_generator::generate_service(t_service* tservice) { generate_service_helpers(tservice); f_service_.indent_down(); - f_service_.indent() << "end" << endl << endl; + f_service_.indent() << "end" << '\n' << '\n'; end_namespace(f_service_, ruby_modules(tservice->get_program())); @@ -831,7 +829,7 @@ void t_rb_generator::generate_service_helpers(t_service* tservice) { vector functions = tservice->get_functions(); vector::iterator f_iter; - f_service_.indent() << "# HELPER FUNCTIONS AND STRUCTURES" << endl << endl; + f_service_.indent() << "# HELPER FUNCTIONS AND STRUCTURES" << '\n' << '\n'; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { t_struct* ts = (*f_iter)->get_arglist(); @@ -874,10 +872,10 @@ void t_rb_generator::generate_service_client(t_service* tservice) { extends_client = " < " + extends + "::Client "; } - f_service_.indent() << "class Client" << extends_client << endl; + f_service_.indent() << "class Client" << extends_client << '\n'; f_service_.indent_up(); - f_service_.indent() << "include ::Thrift::Client" << endl << endl; + f_service_.indent() << "include ::Thrift::Client" << '\n' << '\n'; // Generate client method implementations vector functions = tservice->get_functions(); @@ -889,7 +887,7 @@ void t_rb_generator::generate_service_client(t_service* tservice) { string funname = (*f_iter)->get_name(); // Open function - f_service_.indent() << "def " << function_signature(*f_iter) << endl; + f_service_.indent() << "def " << function_signature(*f_iter) << '\n'; f_service_.indent_up(); f_service_.indent() << "send_" << funname << "("; @@ -902,20 +900,20 @@ void t_rb_generator::generate_service_client(t_service* tservice) { } f_service_ << (*fld_iter)->get_name(); } - f_service_ << ")" << endl; + f_service_ << ")" << '\n'; if (!(*f_iter)->is_oneway()) { f_service_.indent(); if (!(*f_iter)->get_returntype()->is_void()) { f_service_ << "return "; } - f_service_ << "recv_" << funname << "()" << endl; + f_service_ << "recv_" << funname << "()" << '\n'; } f_service_.indent_down(); - f_service_.indent() << "end" << endl; - f_service_ << endl; + f_service_.indent() << "end" << '\n'; + f_service_ << '\n'; - f_service_.indent() << "def send_" << function_signature(*f_iter) << endl; + f_service_.indent() << "def send_" << function_signature(*f_iter) << '\n'; f_service_.indent_up(); std::string argsname = capitalize((*f_iter)->get_name() + "_args"); @@ -927,10 +925,10 @@ void t_rb_generator::generate_service_client(t_service* tservice) { f_service_ << ", :" << (*fld_iter)->get_name() << " => " << (*fld_iter)->get_name(); } - f_service_ << ")" << endl; + f_service_ << ")" << '\n'; f_service_.indent_down(); - f_service_.indent() << "end" << endl; + f_service_.indent() << "end" << '\n'; if (!(*f_iter)->is_oneway()) { std::string resultname = capitalize((*f_iter)->get_name() + "_result"); @@ -940,22 +938,22 @@ void t_rb_generator::generate_service_client(t_service* tservice) { string("recv_") + (*f_iter)->get_name(), &noargs); // Open function - f_service_ << endl; - f_service_.indent() << "def " << function_signature(&recv_function) << endl; + f_service_ << '\n'; + f_service_.indent() << "def " << function_signature(&recv_function) << '\n'; f_service_.indent_up(); - f_service_.indent() << "fname, mtype, rseqid = receive_message_begin()" << endl; - f_service_.indent() << "handle_exception(mtype)" << endl; + f_service_.indent() << "fname, mtype, rseqid = receive_message_begin()" << '\n'; + f_service_.indent() << "handle_exception(mtype)" << '\n'; - f_service_.indent() << "if reply_seqid(rseqid)==false" << endl; - f_service_.indent() << " raise \"seqid reply faild\"" << endl; - f_service_.indent() << "end" << endl; + f_service_.indent() << "if reply_seqid(rseqid)==false" << '\n'; + f_service_.indent() << " raise \"seqid reply faild\"" << '\n'; + f_service_.indent() << "end" << '\n'; - f_service_.indent() << "result = receive_message(" << resultname << ")" << endl; + f_service_.indent() << "result = receive_message(" << resultname << ")" << '\n'; // Careful, only return _result if not a void function if (!(*f_iter)->get_returntype()->is_void()) { - f_service_.indent() << "return result.success unless result.success.nil?" << endl; + f_service_.indent() << "return result.success unless result.success.nil?" << '\n'; } t_struct* xs = (*f_iter)->get_xceptions(); @@ -963,27 +961,27 @@ void t_rb_generator::generate_service_client(t_service* tservice) { vector::const_iterator x_iter; for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { f_service_.indent() << "raise result." << (*x_iter)->get_name() << " unless result." - << (*x_iter)->get_name() << ".nil?" << endl; + << (*x_iter)->get_name() << ".nil?" << '\n'; } // Careful, only return _result if not a void function if ((*f_iter)->get_returntype()->is_void()) { - f_service_.indent() << "return" << endl; + f_service_.indent() << "return" << '\n'; } else { f_service_.indent() << "raise " "::Thrift::ApplicationException.new(::Thrift::ApplicationException::" "MISSING_RESULT, '" << (*f_iter)->get_name() - << " failed: unknown result')" << endl; + << " failed: unknown result')" << '\n'; } // Close function f_service_.indent_down(); - f_service_.indent() << "end" << endl << endl; + f_service_.indent() << "end" << '\n' << '\n'; } } f_service_.indent_down(); - f_service_.indent() << "end" << endl << endl; + f_service_.indent() << "end" << '\n' << '\n'; } /** @@ -1004,10 +1002,10 @@ void t_rb_generator::generate_service_server(t_service* tservice) { } // Generate the header portion - f_service_.indent() << "class Processor" << extends_processor << endl; + f_service_.indent() << "class Processor" << extends_processor << '\n'; f_service_.indent_up(); - f_service_.indent() << "include ::Thrift::Processor" << endl << endl; + f_service_.indent() << "include ::Thrift::Processor" << '\n' << '\n'; // Generate the process subfunctions for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { @@ -1015,7 +1013,7 @@ void t_rb_generator::generate_service_server(t_service* tservice) { } f_service_.indent_down(); - f_service_.indent() << "end" << endl << endl; + f_service_.indent() << "end" << '\n' << '\n'; } /** @@ -1026,13 +1024,13 @@ void t_rb_generator::generate_service_server(t_service* tservice) { void t_rb_generator::generate_process_function(t_service* tservice, t_function* tfunction) { (void)tservice; // Open function - f_service_.indent() << "def process_" << tfunction->get_name() << "(seqid, iprot, oprot)" << endl; + f_service_.indent() << "def process_" << tfunction->get_name() << "(seqid, iprot, oprot)" << '\n'; f_service_.indent_up(); string argsname = capitalize(tfunction->get_name()) + "_args"; string resultname = capitalize(tfunction->get_name()) + "_result"; - f_service_.indent() << "args = read_args(iprot, " << argsname << ")" << endl; + f_service_.indent() << "args = read_args(iprot, " << argsname << ")" << '\n'; t_struct* xs = tfunction->get_xceptions(); const std::vector& xceptions = xs->get_members(); @@ -1040,12 +1038,12 @@ void t_rb_generator::generate_process_function(t_service* tservice, t_function* // Declare result for non oneway function if (!tfunction->is_oneway()) { - f_service_.indent() << "result = " << resultname << ".new()" << endl; + f_service_.indent() << "result = " << resultname << ".new()" << '\n'; } // Try block for a function with exceptions if (xceptions.size() > 0) { - f_service_.indent() << "begin" << endl; + f_service_.indent() << "begin" << '\n'; f_service_.indent_up(); } @@ -1068,37 +1066,37 @@ void t_rb_generator::generate_process_function(t_service* tservice, t_function* } f_service_ << "args." << (*f_iter)->get_name(); } - f_service_ << ")" << endl; + f_service_ << ")" << '\n'; if (!tfunction->is_oneway() && xceptions.size() > 0) { f_service_.indent_down(); for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { f_service_.indent() << "rescue " << full_type_name((*x_iter)->get_type()) << " => " - << (*x_iter)->get_name() << endl; + << (*x_iter)->get_name() << '\n'; if (!tfunction->is_oneway()) { f_service_.indent_up(); f_service_.indent() << "result." << (*x_iter)->get_name() << " = " << (*x_iter)->get_name() - << endl; + << '\n'; f_service_.indent_down(); } } - f_service_.indent() << "end" << endl; + f_service_.indent() << "end" << '\n'; } // Shortcut out here for oneway functions if (tfunction->is_oneway()) { - f_service_.indent() << "return" << endl; + f_service_.indent() << "return" << '\n'; f_service_.indent_down(); - f_service_.indent() << "end" << endl << endl; + f_service_.indent() << "end" << '\n' << '\n'; return; } f_service_.indent() << "write_result(result, oprot, '" << tfunction->get_name() << "', seqid)" - << endl; + << '\n'; // Close function f_service_.indent_down(); - f_service_.indent() << "end" << endl << endl; + f_service_.indent() << "end" << '\n' << '\n'; } /** @@ -1219,7 +1217,7 @@ void t_rb_generator::generate_rdoc(t_rb_ofstream& out, t_doc* tdoc) { } void t_rb_generator::generate_rb_struct_required_validator(t_rb_ofstream& out, t_struct* tstruct) { - out.indent() << "def validate" << endl; + out.indent() << "def validate" << '\n'; out.indent_up(); const vector& fields = tstruct->get_members(); @@ -1235,7 +1233,7 @@ void t_rb_generator::generate_rb_struct_required_validator(t_rb_ofstream& out, t } else { out << " unless @" << field->get_name(); } - out << endl; + out << '\n'; } } @@ -1246,21 +1244,21 @@ void t_rb_generator::generate_rb_struct_required_validator(t_rb_ofstream& out, t if (field->get_type()->is_enum()) { out.indent() << "unless @" << field->get_name() << ".nil? || " << full_type_name(field->get_type()) << "::VALID_VALUES.include?(@" - << field->get_name() << ")" << endl; + << field->get_name() << ")" << '\n'; out.indent_up(); out.indent() << "raise ::Thrift::ProtocolException.new(::Thrift::ProtocolException::UNKNOWN, " - "'Invalid value of field " << field->get_name() << "!')" << endl; + "'Invalid value of field " << field->get_name() << "!')" << '\n'; out.indent_down(); - out.indent() << "end" << endl; + out.indent() << "end" << '\n'; } } out.indent_down(); - out.indent() << "end" << endl << endl; + out.indent() << "end" << '\n' << '\n'; } void t_rb_generator::generate_rb_union_validator(t_rb_ofstream& out, t_struct* tstruct) { - out.indent() << "def validate" << endl; + out.indent() << "def validate" << '\n'; out.indent_up(); const vector& fields = tstruct->get_members(); @@ -1268,25 +1266,25 @@ void t_rb_generator::generate_rb_union_validator(t_rb_ofstream& out, t_struct* t out.indent() << "raise(StandardError, 'Union fields are not set.') if get_set_field.nil? || get_value.nil?" - << endl; + << '\n'; // if field is an enum, check that its value is valid for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { const t_field* field = (*f_iter); if (field->get_type()->is_enum()) { - out.indent() << "if get_set_field == :" << field->get_name() << endl; + out.indent() << "if get_set_field == :" << field->get_name() << '\n'; out.indent() << " raise " "::Thrift::ProtocolException.new(::Thrift::ProtocolException::UNKNOWN, " "'Invalid value of field " << field->get_name() << "!') unless " << full_type_name(field->get_type()) << "::VALID_VALUES.include?(get_value)" - << endl; - out.indent() << "end" << endl; + << '\n'; + out.indent() << "end" << '\n'; } } out.indent_down(); - out.indent() << "end" << endl << endl; + out.indent() << "end" << '\n' << '\n'; } std::string t_rb_generator::display_name() const { diff --git a/compiler/cpp/src/thrift/generate/t_rs_generator.cc b/compiler/cpp/src/thrift/generate/t_rs_generator.cc index 2742724a605..e336077e15f 100644 --- a/compiler/cpp/src/thrift/generate/t_rs_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_rs_generator.cc @@ -31,7 +31,6 @@ using std::set; using std::string; using std::vector; -static const string endl("\n"); // avoid ostream << std::endl flushes static const string SERVICE_RESULT_VARIABLE("result_value"); static const string RESULT_STRUCT_SUFFIX("Result"); static const string RUST_RESERVED_WORDS[] @@ -521,9 +520,9 @@ void t_rs_generator::init_generator() { f_gen_.open(f_gen_name.c_str()); // header comment - f_gen_ << "// " << autogen_summary() << endl; - f_gen_ << "// DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING" << endl; - f_gen_ << endl; + f_gen_ << "// " << autogen_summary() << '\n'; + f_gen_ << "// DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING" << '\n'; + f_gen_ << '\n'; render_attributes_and_includes(); } @@ -532,11 +531,11 @@ void t_rs_generator::render_attributes_and_includes() { // turn off some compiler/clippy warnings // code may not be used - f_gen_ << "#![allow(dead_code)]" << endl; + f_gen_ << "#![allow(dead_code)]" << '\n'; // code always includes BTreeMap/BTreeSet/OrderedFloat - f_gen_ << "#![allow(unused_imports)]" << endl; + f_gen_ << "#![allow(unused_imports)]" << '\n'; // code might not include imports from crates - f_gen_ << "#![allow(unused_extern_crates)]" << endl; + f_gen_ << "#![allow(unused_extern_crates)]" << '\n'; // constructors take *all* struct parameters, which can trigger the "too many arguments" warning // some auto-gen'd types can be deeply nested. clippy recommends factoring them out which is hard // to autogen some methods may start with "is_" @@ -548,38 +547,38 @@ void t_rs_generator::render_attributes_and_includes() { // 2. When you define types out of order f_gen_ << "#![allow(clippy::too_many_arguments, clippy::type_complexity, clippy::vec_box, " "clippy::wrong_self_convention)]" - << endl; + << '\n'; // prevent rustfmt from running against this file // lines are too long, code is (thankfully!) not visual-indented, etc. // can't use #[rustfmt::skip] see: https://github.com/rust-lang/rust/issues/54726 - f_gen_ << "#![cfg_attr(rustfmt, rustfmt_skip)]" << endl; - f_gen_ << endl; + f_gen_ << "#![cfg_attr(rustfmt, rustfmt_skip)]" << '\n'; + f_gen_ << '\n'; // add standard includes - f_gen_ << "use std::cell::RefCell;" << endl; - f_gen_ << "use std::collections::{BTreeMap, BTreeSet};" << 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_ << endl; - f_gen_ << "use thrift::OrderedFloat;" << endl; + f_gen_ << "use std::cell::RefCell;" << '\n'; + f_gen_ << "use std::collections::{BTreeMap, BTreeSet};" << '\n'; + f_gen_ << "use std::convert::{From, TryFrom};" << '\n'; + f_gen_ << "use std::default::Default;" << '\n'; + f_gen_ << "use std::error::Error;" << '\n'; + f_gen_ << "use std::fmt;" << '\n'; + f_gen_ << "use std::fmt::{Display, Formatter};" << '\n'; + f_gen_ << "use std::rc::Rc;" << '\n'; + f_gen_ << '\n'; + f_gen_ << "use thrift::OrderedFloat;" << '\n'; f_gen_ << "use thrift::{ApplicationError, ApplicationErrorKind, ProtocolError, " "ProtocolErrorKind, TThriftClient};" - << endl; + << '\n'; f_gen_ << "use thrift::protocol::{TFieldIdentifier, TListIdentifier, TMapIdentifier, " "TMessageIdentifier, TMessageType, TInputProtocol, TOutputProtocol, TSerializable, " "TSetIdentifier, TStructIdentifier, TType};" - << endl; - f_gen_ << "use thrift::protocol::field_id;" << endl; - f_gen_ << "use thrift::protocol::verify_expected_message_type;" << endl; - f_gen_ << "use thrift::protocol::verify_expected_sequence_number;" << endl; - f_gen_ << "use thrift::protocol::verify_expected_service_call;" << endl; - f_gen_ << "use thrift::protocol::verify_required_field_exists;" << endl; - f_gen_ << "use thrift::server::TProcessor;" << endl; - f_gen_ << endl; + << '\n'; + f_gen_ << "use thrift::protocol::field_id;" << '\n'; + f_gen_ << "use thrift::protocol::verify_expected_message_type;" << '\n'; + f_gen_ << "use thrift::protocol::verify_expected_sequence_number;" << '\n'; + f_gen_ << "use thrift::protocol::verify_expected_service_call;" << '\n'; + f_gen_ << "use thrift::protocol::verify_required_field_exists;" << '\n'; + f_gen_ << "use thrift::server::TProcessor;" << '\n'; + f_gen_ << '\n'; // add all the program includes // NOTE: this is more involved than you would expect because of service extension @@ -615,13 +614,13 @@ void t_rs_generator::render_attributes_and_includes() { string_replace(module_namespace, ".", "::"); if (module_namespace.empty()) { - f_gen_ << "use crate::" << rust_snake_case(module_name) << ";" << endl; + f_gen_ << "use crate::" << rust_snake_case(module_name) << ";" << '\n'; } else { f_gen_ << "use crate::" << module_namespace << "::" << rust_snake_case(module_name) << ";" - << endl; + << '\n'; } } - f_gen_ << endl; + f_gen_ << '\n'; } } @@ -673,8 +672,8 @@ void t_rs_generator::render_const_value(const string& name, t_type* ttype, t_con f_gen_ << "pub const " << rust_upper_case(name) << ": " << to_rust_const_type(ttype) << " = "; render_const_value(ttype, tvalue, false); - f_gen_ << ";" << endl; - f_gen_ << endl; + f_gen_ << ";" << '\n'; + f_gen_ << '\n'; } void t_rs_generator::render_const_value_holder(const string& name, @@ -686,19 +685,19 @@ void t_rs_generator::render_const_value_holder(const string& name, string holder_name("Const" + rust_camel_case(name)); - f_gen_ << indent() << "pub struct " << holder_name << ";" << endl; - f_gen_ << indent() << "impl " << holder_name << " {" << endl; + f_gen_ << indent() << "pub struct " << holder_name << ";" << '\n'; + f_gen_ << indent() << "impl " << holder_name << " {" << '\n'; indent_up(); - f_gen_ << indent() << "pub fn const_value() -> " << to_rust_type(ttype) << " {" << endl; + f_gen_ << indent() << "pub fn const_value() -> " << to_rust_type(ttype) << " {" << '\n'; indent_up(); render_const_value(ttype, tvalue, true, false); indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; - f_gen_ << endl; + f_gen_ << indent() << "}" << '\n'; + f_gen_ << '\n'; } void t_rs_generator::render_const_value(t_type* ttype, @@ -748,10 +747,10 @@ void t_rs_generator::render_const_value(t_type* ttype, } else if (ttype->is_typedef()) { render_const_value(get_true_type(ttype), tvalue, is_owned, true); } else if (ttype->is_enum()) { - f_gen_ << "{" << endl; + f_gen_ << "{" << '\n'; indent_up(); - f_gen_ << indent() << to_rust_type(ttype) << "::try_from(" << tvalue->get_integer() - << ").expect(\"expecting valid const value\")" << endl; + f_gen_ << indent() << to_rust_type(ttype) << "::from(" << tvalue->get_integer() + << ")" << '\n'; indent_down(); f_gen_ << indent() << "}"; } else if (ttype->is_struct() || ttype->is_xception()) { @@ -772,21 +771,21 @@ void t_rs_generator::render_const_value(t_type* ttype, } if (!is_inline) { - f_gen_ << endl; + f_gen_ << '\n'; } } void t_rs_generator::render_const_struct(t_type* ttype, t_const_value*) { if (((t_struct*)ttype)->is_union()) { - f_gen_ << "{" << endl; + f_gen_ << "{" << '\n'; indent_up(); - f_gen_ << indent() << "unimplemented!()" << endl; + f_gen_ << indent() << "unimplemented!()" << '\n'; indent_down(); f_gen_ << indent() << "}"; } else { - f_gen_ << "{" << endl; + f_gen_ << "{" << '\n'; indent_up(); - f_gen_ << indent() << "unimplemented!()" << endl; + f_gen_ << indent() << "unimplemented!()" << '\n'; indent_down(); f_gen_ << indent() << "}"; } @@ -794,7 +793,7 @@ void t_rs_generator::render_const_struct(t_type* ttype, t_const_value*) { void t_rs_generator::render_const_list(t_type* ttype, t_const_value* tvalue) { t_type* elem_type = ((t_list*)ttype)->get_elem_type(); - f_gen_ << "vec![" << endl; + f_gen_ << "vec![" << '\n'; indent_up(); const vector& elems = tvalue->get_list(); vector::const_iterator elem_iter; @@ -802,7 +801,7 @@ void t_rs_generator::render_const_list(t_type* ttype, t_const_value* tvalue) { f_gen_ << indent(); t_const_value* elem_value = (*elem_iter); render_const_value(elem_type, elem_value); - f_gen_ << "," << endl; + f_gen_ << "," << '\n'; } indent_down(); f_gen_ << indent() << "]"; @@ -810,7 +809,7 @@ void t_rs_generator::render_const_list(t_type* ttype, t_const_value* tvalue) { void t_rs_generator::render_const_set(t_type* ttype, t_const_value* tvalue) { t_type* elem_type = ((t_set*)ttype)->get_elem_type(); - f_gen_ << "BTreeSet::from([" << endl; + f_gen_ << "BTreeSet::from([" << '\n'; indent_up(); const vector& elems = tvalue->get_list(); vector::const_iterator elem_iter; @@ -818,7 +817,7 @@ void t_rs_generator::render_const_set(t_type* ttype, t_const_value* tvalue) { f_gen_ << indent(); t_const_value* elem_value = (*elem_iter); render_const_value(elem_type, elem_value); - f_gen_ << "," << endl; + f_gen_ << "," << '\n'; } indent_down(); f_gen_ << indent() << "])"; @@ -827,7 +826,7 @@ void t_rs_generator::render_const_set(t_type* ttype, t_const_value* tvalue) { void t_rs_generator::render_const_map(t_type* ttype, t_const_value* tvalue) { t_type* key_type = ((t_map*)ttype)->get_key_type(); t_type* val_type = ((t_map*)ttype)->get_val_type(); - f_gen_ << "BTreeMap::from([" << endl; + f_gen_ << "BTreeMap::from([" << '\n'; indent_up(); const map& elems = tvalue->get_map(); @@ -836,16 +835,16 @@ void t_rs_generator::render_const_map(t_type* ttype, t_const_value* tvalue) { t_const_value* key_value = elem_iter->first; t_const_value* val_value = elem_iter->second; - f_gen_ << indent() << "(" << endl; + f_gen_ << indent() << "(" << '\n'; indent_up(); f_gen_ << indent(); render_const_value(key_type, key_value); - f_gen_ << "," << endl; + f_gen_ << "," << '\n'; f_gen_ << indent(); render_const_value(val_type, val_value); - f_gen_ << "," << endl; + f_gen_ << "," << '\n'; indent_down(); - f_gen_ << indent() << ")," << endl; + f_gen_ << indent() << ")," << '\n'; } indent_down(); f_gen_ << indent() << "])"; @@ -860,8 +859,8 @@ void t_rs_generator::render_const_map(t_type* ttype, t_const_value* tvalue) { void t_rs_generator::generate_typedef(t_typedef* ttypedef) { std::string actual_type = to_rust_type(ttypedef->get_type()); f_gen_ << "pub type " << rust_safe_name(ttypedef->get_symbolic()) << " = " << actual_type << ";" - << endl; - f_gen_ << endl; + << '\n'; + f_gen_ << '\n'; } //----------------------------------------------------------------------------- @@ -879,13 +878,13 @@ void t_rs_generator::generate_enum(t_enum* tenum) { void t_rs_generator::render_enum_definition(t_enum* tenum, const string& enum_name) { render_rustdoc((t_doc*)tenum); - f_gen_ << "#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]" << endl; - f_gen_ << "pub struct " << enum_name << "(pub i32);" << endl; - f_gen_ << endl; + f_gen_ << "#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]" << '\n'; + f_gen_ << "pub struct " << enum_name << "(pub i32);" << '\n'; + f_gen_ << '\n'; } void t_rs_generator::render_enum_impl(t_enum* tenum, const string& enum_name) { - f_gen_ << "impl " << enum_name << " {" << endl; + f_gen_ << "impl " << enum_name << " {" << '\n'; indent_up(); vector constants = tenum->get_constants(); @@ -898,114 +897,114 @@ void t_rs_generator::render_enum_impl(t_enum* tenum, const string& enum_name) { render_rustdoc((t_doc*)val); f_gen_ << indent() << "pub const " << rust_enum_variant_name(val->get_name()) << ": " << enum_name << " = " << enum_name << "(" << val->get_value() << ")" - << ";" << endl; + << ";" << '\n'; } } // array containing all IDL-defined enum variants { - f_gen_ << indent() << "pub const ENUM_VALUES: &'static [Self] = &[" << endl; + f_gen_ << indent() << "pub const ENUM_VALUES: &'static [Self] = &[" << '\n'; indent_up(); vector::iterator constants_iter; for (constants_iter = constants.begin(); constants_iter != constants.end(); ++constants_iter) { t_enum_value* val = (*constants_iter); - f_gen_ << indent() << "Self::" << rust_enum_variant_name(val->get_name()) << "," << endl; + f_gen_ << indent() << "Self::" << rust_enum_variant_name(val->get_name()) << "," << '\n'; } indent_down(); - f_gen_ << indent() << "];" << endl; + f_gen_ << indent() << "];" << '\n'; } indent_down(); - f_gen_ << "}" << endl; - f_gen_ << endl; + f_gen_ << "}" << '\n'; + f_gen_ << '\n'; - f_gen_ << "impl TSerializable for " << enum_name << " {" << endl; + f_gen_ << "impl TSerializable for " << enum_name << " {" << '\n'; indent_up(); - f_gen_ << indent() << "#[allow(clippy::trivially_copy_pass_by_ref)]" << endl; + f_gen_ << indent() << "#[allow(clippy::trivially_copy_pass_by_ref)]" << '\n'; f_gen_ << indent() << "fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> {" - << endl; + << '\n'; indent_up(); - f_gen_ << indent() << "o_prot.write_i32(self.0)" << endl; + f_gen_ << indent() << "o_prot.write_i32(self.0)" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; f_gen_ << indent() << "fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result<" - << enum_name << "> {" << endl; + << enum_name << "> {" << '\n'; indent_up(); - f_gen_ << indent() << "let enum_value = i_prot.read_i32()?;" << endl; + f_gen_ << indent() << "let enum_value = i_prot.read_i32()?;" << '\n'; f_gen_ << indent() << "Ok(" << enum_name << "::from(enum_value)" - << ")" << endl; + << ")" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; indent_down(); - f_gen_ << "}" << endl; - f_gen_ << endl; + f_gen_ << "}" << '\n'; + f_gen_ << '\n'; } void t_rs_generator::render_enum_conversion(t_enum* tenum, const string& enum_name) { // From trait: i32 -> ENUM_TYPE - f_gen_ << "impl From for " << enum_name << " {" << endl; + f_gen_ << "impl From for " << enum_name << " {" << '\n'; indent_up(); - f_gen_ << indent() << "fn from(i: i32) -> Self {" << endl; + f_gen_ << indent() << "fn from(i: i32) -> Self {" << '\n'; indent_up(); - f_gen_ << indent() << "match i {" << endl; + f_gen_ << indent() << "match i {" << '\n'; indent_up(); vector constants = tenum->get_constants(); vector::iterator constants_iter; for (constants_iter = constants.begin(); constants_iter != constants.end(); ++constants_iter) { t_enum_value* val = (*constants_iter); f_gen_ << indent() << val->get_value() << " => " << enum_name - << "::" << rust_enum_variant_name(val->get_name()) << "," << endl; + << "::" << rust_enum_variant_name(val->get_name()) << "," << '\n'; } - f_gen_ << indent() << "_ => " << enum_name << "(i)" << endl; + f_gen_ << indent() << "_ => " << enum_name << "(i)" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; indent_down(); - f_gen_ << "}" << endl; - f_gen_ << endl; + f_gen_ << "}" << '\n'; + f_gen_ << '\n'; // From trait: &i32 -> ENUM_TYPE - f_gen_ << "impl From<&i32> for " << enum_name << " {" << endl; + f_gen_ << "impl From<&i32> for " << enum_name << " {" << '\n'; indent_up(); - f_gen_ << indent() << "fn from(i: &i32) -> Self {" << endl; + f_gen_ << indent() << "fn from(i: &i32) -> Self {" << '\n'; indent_up(); - f_gen_ << indent() << enum_name << "::from(*i)" << endl; + f_gen_ << indent() << enum_name << "::from(*i)" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; indent_down(); - f_gen_ << "}" << endl; - f_gen_ << endl; + f_gen_ << "}" << '\n'; + f_gen_ << '\n'; // From trait: ENUM_TYPE -> int - f_gen_ << "impl From<" << enum_name << "> for i32 {" << endl; + f_gen_ << "impl From<" << enum_name << "> for i32 {" << '\n'; indent_up(); - f_gen_ << indent() << "fn from(e: " << enum_name << ") -> i32 {" << endl; + f_gen_ << indent() << "fn from(e: " << enum_name << ") -> i32 {" << '\n'; indent_up(); - f_gen_ << indent() << "e.0" << endl; + f_gen_ << indent() << "e.0" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; indent_down(); - f_gen_ << "}" << endl; - f_gen_ << endl; + f_gen_ << "}" << '\n'; + f_gen_ << '\n'; // From trait: &ENUM_TYPE -> int - f_gen_ << "impl From<&" << enum_name << "> for i32 {" << endl; + f_gen_ << "impl From<&" << enum_name << "> for i32 {" << '\n'; indent_up(); - f_gen_ << indent() << "fn from(e: &" << enum_name << ") -> i32 {" << endl; + f_gen_ << indent() << "fn from(e: &" << enum_name << ") -> i32 {" << '\n'; indent_up(); - f_gen_ << indent() << "e.0" << endl; + f_gen_ << indent() << "e.0" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; indent_down(); - f_gen_ << "}" << endl; - f_gen_ << endl; + f_gen_ << "}" << '\n'; + f_gen_ << '\n'; } //----------------------------------------------------------------------------- @@ -1056,8 +1055,8 @@ void t_rs_generator::render_struct_definition(const string& struct_name, } } f_gen_ << "#[derive(Clone, Debug" << (need_default ? ", Default" : "") - << ", Eq, Hash, Ord, PartialEq, PartialOrd)]" << endl; - f_gen_ << visibility_qualifier(struct_type) << "struct " << struct_name << " {" << endl; + << ", Eq, Hash, Ord, PartialEq, PartialOrd)]" << '\n'; + f_gen_ << visibility_qualifier(struct_type) << "struct " << struct_name << " {" << '\n'; // render the members if (!members.empty()) { @@ -1072,53 +1071,53 @@ void t_rs_generator::render_struct_definition(const string& struct_name, render_rustdoc((t_doc*)member); f_gen_ << indent() << visibility_qualifier(struct_type) << rust_field_name(member) << ": " - << rust_type << "," << endl; + << rust_type << "," << '\n'; } indent_down(); } - f_gen_ << "}" << endl; - f_gen_ << endl; + f_gen_ << "}" << '\n'; + f_gen_ << '\n'; } void t_rs_generator::render_exception_struct_error_trait_impls(const string& struct_name, t_struct* tstruct) { // error::Error trait - f_gen_ << "impl Error for " << struct_name << " {}" << endl; - f_gen_ << endl; + f_gen_ << "impl Error for " << struct_name << " {}" << '\n'; + f_gen_ << '\n'; // convert::From trait - f_gen_ << "impl From<" << struct_name << "> for thrift::Error {" << endl; + f_gen_ << "impl From<" << struct_name << "> for thrift::Error {" << '\n'; indent_up(); - f_gen_ << indent() << "fn from(e: " << struct_name << ") -> Self {" << endl; + f_gen_ << indent() << "fn from(e: " << struct_name << ") -> Self {" << '\n'; indent_up(); - f_gen_ << indent() << "thrift::Error::User(Box::new(e))" << endl; + f_gen_ << indent() << "thrift::Error::User(Box::new(e))" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; indent_down(); - f_gen_ << "}" << endl; - f_gen_ << endl; + f_gen_ << "}" << '\n'; + f_gen_ << '\n'; // fmt::Display trait - f_gen_ << "impl Display for " << struct_name << " {" << endl; + f_gen_ << "impl Display for " << struct_name << " {" << '\n'; indent_up(); - f_gen_ << indent() << "fn fmt(&self, f: &mut Formatter) -> fmt::Result {" << endl; + f_gen_ << indent() << "fn fmt(&self, f: &mut Formatter) -> fmt::Result {" << '\n'; indent_up(); f_gen_ << indent() << "write!(f, " << "\"remote service threw " << tstruct->get_name() << "\"" // use *original* name - << ")" << endl; + << ")" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; indent_down(); - f_gen_ << "}" << endl; - f_gen_ << endl; + f_gen_ << "}" << '\n'; + f_gen_ << '\n'; } void t_rs_generator::render_struct_impl(const string& struct_name, t_struct* tstruct, t_rs_generator::e_struct_type struct_type) { - f_gen_ << "impl " << struct_name << " {" << endl; + f_gen_ << "impl " << struct_name << " {" << '\n'; indent_up(); if (struct_type == t_rs_generator::T_REGULAR || struct_type == t_rs_generator::T_EXCEPTION) { @@ -1131,10 +1130,10 @@ void t_rs_generator::render_struct_impl(const string& struct_name, if (struct_type == t_rs_generator::T_REGULAR || struct_type == t_rs_generator::T_EXCEPTION) { indent_down(); - f_gen_ << "}" << endl; - f_gen_ << endl; + f_gen_ << "}" << '\n'; + f_gen_ << '\n'; - f_gen_ << "impl TSerializable for " << struct_name << " {" << endl; + f_gen_ << "impl TSerializable for " << struct_name << " {" << '\n'; indent_up(); } @@ -1142,8 +1141,8 @@ void t_rs_generator::render_struct_impl(const string& struct_name, render_struct_sync_write(tstruct, struct_type); indent_down(); - f_gen_ << "}" << endl; - f_gen_ << endl; + f_gen_ << "}" << '\n'; + f_gen_ << '\n'; } void t_rs_generator::render_struct_constructor(const string& struct_name, @@ -1213,13 +1212,13 @@ void t_rs_generator::render_struct_constructor(const string& struct_name, string visibility(visibility_qualifier(struct_type)); f_gen_ << indent() << visibility << "fn new" << type_parameter_string << "(" << arg_string - << ") -> " << struct_name << " " << type_qualifier_string << "{" << endl; + << ") -> " << struct_name << " " << type_qualifier_string << "{" << '\n'; indent_up(); if (members.empty()) { - f_gen_ << indent() << struct_name << " {}" << endl; + f_gen_ << indent() << struct_name << " {}" << '\n'; } else { - f_gen_ << indent() << struct_name << " {" << endl; + f_gen_ << indent() << struct_name << " {" << '\n'; indent_up(); for (members_iter = members.begin(); members_iter != members.end(); ++members_iter) { @@ -1228,18 +1227,18 @@ void t_rs_generator::render_struct_constructor(const string& struct_name, string member_name(rust_field_name(member)); if (is_optional(member_req)) { - f_gen_ << indent() << member_name << ": " << member_name << ".into()," << endl; + f_gen_ << indent() << member_name << ": " << member_name << ".into()," << '\n'; } else { - f_gen_ << indent() << member_name << "," << endl; + f_gen_ << indent() << member_name << "," << '\n'; } } indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; } indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; } void t_rs_generator::render_result_struct_to_result_method(t_struct* tstruct) { @@ -1272,7 +1271,7 @@ void t_rs_generator::render_result_struct_to_result_method(t_struct* tstruct) { // maintaining a rendered branch count (while a little ugly) got me the // rendering I wanted with code that was reasonably understandable - f_gen_ << indent() << "fn ok_or(self) -> thrift::Result<" << rust_return_type << "> {" << endl; + f_gen_ << indent() << "fn ok_or(self) -> thrift::Result<" << rust_return_type << "> {" << '\n'; indent_up(); int rendered_branch_count = 0; @@ -1284,10 +1283,10 @@ void t_rs_generator::render_result_struct_to_result_method(t_struct* tstruct) { string field_name("self." + rust_field_name(tfield)); string branch_statement = rendered_branch_count == 0 ? "if" : "} else if"; - f_gen_ << indent() << branch_statement << " " << field_name << ".is_some() {" << endl; + f_gen_ << indent() << branch_statement << " " << field_name << ".is_some() {" << '\n'; indent_up(); f_gen_ << indent() << "Err(thrift::Error::User(Box::new(" << field_name << ".unwrap())))" - << endl; + << '\n'; indent_down(); rendered_branch_count++; @@ -1299,35 +1298,35 @@ void t_rs_generator::render_result_struct_to_result_method(t_struct* tstruct) { if (rendered_branch_count == 0) { // we have the unit return and this service call has no user-defined // exceptions. this means that we've a trivial return (happens with oneways) - f_gen_ << indent() << "Ok(())" << endl; + f_gen_ << indent() << "Ok(())" << '\n'; } else { // we have the unit return, but there are user-defined exceptions // if we've gotten this far then we have the default return (i.e. call successful) - f_gen_ << indent() << "} else {" << endl; + f_gen_ << indent() << "} else {" << '\n'; indent_up(); - f_gen_ << indent() << "Ok(())" << endl; + f_gen_ << indent() << "Ok(())" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; } } else { string branch_statement = rendered_branch_count == 0 ? "if" : "} else if"; f_gen_ << indent() << branch_statement << " self." << SERVICE_RESULT_VARIABLE << ".is_some() {" - << endl; + << '\n'; indent_up(); - f_gen_ << indent() << "Ok(self." << SERVICE_RESULT_VARIABLE << ".unwrap())" << endl; + f_gen_ << indent() << "Ok(self." << SERVICE_RESULT_VARIABLE << ".unwrap())" << '\n'; indent_down(); - f_gen_ << indent() << "} else {" << endl; + f_gen_ << indent() << "} else {" << '\n'; indent_up(); // if we haven't found a valid return value *or* a user exception // then we're in trouble; return a default error render_thrift_error("Application", "ApplicationError", "ApplicationErrorKind::MissingResult", "\"no result received for " + service_call_name + "\""); indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; } indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; } void t_rs_generator::render_union(t_struct* tstruct) { @@ -1343,32 +1342,32 @@ void t_rs_generator::render_union_definition(const string& union_name, t_struct* throw "cannot generate rust enum with 0 members"; // may be valid thrift, but it's invalid rust } - f_gen_ << "#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]" << endl; - f_gen_ << "pub enum " << union_name << " {" << endl; + f_gen_ << "#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]" << '\n'; + f_gen_ << "pub enum " << union_name << " {" << '\n'; indent_up(); vector::const_iterator member_iter; for (member_iter = members.begin(); member_iter != members.end(); ++member_iter) { t_field* tfield = (*member_iter); f_gen_ << indent() << rust_union_field_name(tfield) << "(" << to_rust_type(tfield->get_type()) - << ")," << endl; + << ")," << '\n'; } indent_down(); - f_gen_ << "}" << endl; - f_gen_ << endl; + f_gen_ << "}" << '\n'; + f_gen_ << '\n'; } void t_rs_generator::render_union_impl(const string& union_name, t_struct* tstruct) { - f_gen_ << "impl TSerializable for " << union_name << " {" << endl; + f_gen_ << "impl TSerializable for " << union_name << " {" << '\n'; indent_up(); render_union_sync_read(union_name, tstruct); render_union_sync_write(union_name, tstruct); indent_down(); - f_gen_ << "}" << endl; - f_gen_ << endl; + f_gen_ << "}" << '\n'; + f_gen_ << '\n'; } //----------------------------------------------------------------------------- @@ -1382,14 +1381,14 @@ void t_rs_generator::render_struct_sync_write(t_struct* tstruct, f_gen_ << indent() << "fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> {" - << endl; + << '\n'; indent_up(); // write struct header to output protocol // note: use the *original* struct name here f_gen_ << indent() - << "let struct_ident = TStructIdentifier::new(\"" + tstruct->get_name() + "\");" << endl; - f_gen_ << indent() << "o_prot.write_struct_begin(&struct_ident)?;" << endl; + << "let struct_ident = TStructIdentifier::new(\"" + tstruct->get_name() + "\");" << '\n'; + f_gen_ << indent() << "o_prot.write_struct_begin(&struct_ident)?;" << '\n'; // write struct members to output protocol vector members = tstruct->get_sorted_members(); @@ -1404,30 +1403,30 @@ void t_rs_generator::render_struct_sync_write(t_struct* tstruct, } // write struct footer to output protocol - f_gen_ << indent() << "o_prot.write_field_stop()?;" << endl; - f_gen_ << indent() << "o_prot.write_struct_end()" << endl; + f_gen_ << indent() << "o_prot.write_field_stop()?;" << '\n'; + f_gen_ << indent() << "o_prot.write_struct_end()" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; } void t_rs_generator::render_union_sync_write(const string& union_name, t_struct* tstruct) { f_gen_ << indent() << "fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> {" - << endl; + << '\n'; indent_up(); // write struct header to output protocol // note: use the *original* struct name here f_gen_ << indent() - << "let struct_ident = TStructIdentifier::new(\"" + tstruct->get_name() + "\");" << endl; - f_gen_ << indent() << "o_prot.write_struct_begin(&struct_ident)?;" << endl; + << "let struct_ident = TStructIdentifier::new(\"" + tstruct->get_name() + "\");" << '\n'; + f_gen_ << indent() << "o_prot.write_struct_begin(&struct_ident)?;" << '\n'; // write the enum field to the output protocol vector members = tstruct->get_sorted_members(); if (!members.empty()) { - f_gen_ << indent() << "match *self {" << endl; + f_gen_ << indent() << "match *self {" << '\n'; indent_up(); vector::iterator members_iter; for (members_iter = members.begin(); members_iter != members.end(); ++members_iter) { @@ -1440,22 +1439,22 @@ void t_rs_generator::render_union_sync_write(const string& union_name, t_struct* } string match_var((ttype->is_base_type() && !ttype->is_string()) ? "f" : "ref f"); f_gen_ << indent() << union_name << "::" << rust_union_field_name(member) << "(" << match_var - << ") => {" << endl; + << ") => {" << '\n'; indent_up(); render_struct_field_sync_write("f", true, member, member_req); indent_down(); - f_gen_ << indent() << "}," << endl; + f_gen_ << indent() << "}," << '\n'; } indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; } // write struct footer to output protocol - f_gen_ << indent() << "o_prot.write_field_stop()?;" << endl; - f_gen_ << indent() << "o_prot.write_struct_end()" << endl; + f_gen_ << indent() << "o_prot.write_field_stop()?;" << '\n'; + f_gen_ << indent() << "o_prot.write_struct_end()" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; } void t_rs_generator::render_struct_field_sync_write(const string& field_var, @@ -1475,23 +1474,23 @@ void t_rs_generator::render_struct_field_sync_write(const string& field_var, if (is_optional(req)) { string let_var((actual_type->is_base_type() && !actual_type->is_string()) ? "fld_var" : "ref fld_var"); - f_gen_ << indent() << "if let Some(" << let_var << ") = " << field_var << " {" << endl; + f_gen_ << indent() << "if let Some(" << let_var << ") = " << field_var << " {" << '\n'; indent_up(); - f_gen_ << indent() << "o_prot.write_field_begin(&" << field_ident_string << ")?;" << endl; + f_gen_ << indent() << "o_prot.write_field_begin(&" << field_ident_string << ")?;" << '\n'; render_type_sync_write("fld_var", true, field_type); - f_gen_ << indent() << "o_prot.write_field_end()?" << endl; + f_gen_ << indent() << "o_prot.write_field_end()?" << '\n'; indent_down(); /* FIXME: rethink how I deal with OPT_IN_REQ_OUT if (req == t_field::T_OPT_IN_REQ_OUT) { - f_gen_ << indent() << "let field_ident = " << field_ident_string << ";" << endl; - f_gen_ << indent() << "o_prot.write_field_begin(&field_ident)?;" << endl; - f_gen_ << indent() << "o_prot.write_field_end()?;" << endl; + f_gen_ << indent() << "let field_ident = " << field_ident_string << ";" << '\n'; + f_gen_ << indent() << "o_prot.write_field_begin(&field_ident)?;" << '\n'; + f_gen_ << indent() << "o_prot.write_field_end()?;" << '\n'; }*/ - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; } else { - f_gen_ << indent() << "o_prot.write_field_begin(&" << field_ident_string << ")?;" << endl; + f_gen_ << indent() << "o_prot.write_field_begin(&" << field_ident_string << ")?;" << '\n'; render_type_sync_write(field_var, field_var_is_ref, tfield->get_type()); - f_gen_ << indent() << "o_prot.write_field_end()?;" << endl; + f_gen_ << indent() << "o_prot.write_field_end()?;" << '\n'; } } @@ -1506,32 +1505,32 @@ void t_rs_generator::render_type_sync_write(const string& type_var, case t_base_type::TYPE_STRING: { string ref(type_var_is_ref ? "" : "&"); if (tbase_type->is_binary()) { - f_gen_ << indent() << "o_prot.write_bytes(" + ref + type_var + ")?;" << endl; + f_gen_ << indent() << "o_prot.write_bytes(" + ref + type_var + ")?;" << '\n'; } else { - f_gen_ << indent() << "o_prot.write_string(" + ref + type_var + ")?;" << endl; + f_gen_ << indent() << "o_prot.write_string(" + ref + type_var + ")?;" << '\n'; } return; } case t_base_type::TYPE_UUID: - f_gen_ << indent() << "o_prot.write_uuid(&" + type_var + ")?;" << endl; + f_gen_ << indent() << "o_prot.write_uuid(&" + type_var + ")?;" << '\n'; return; case t_base_type::TYPE_BOOL: - f_gen_ << indent() << "o_prot.write_bool(" + type_var + ")?;" << endl; + f_gen_ << indent() << "o_prot.write_bool(" + type_var + ")?;" << '\n'; return; case t_base_type::TYPE_I8: - f_gen_ << indent() << "o_prot.write_i8(" + type_var + ")?;" << endl; + f_gen_ << indent() << "o_prot.write_i8(" + type_var + ")?;" << '\n'; return; case t_base_type::TYPE_I16: - f_gen_ << indent() << "o_prot.write_i16(" + type_var + ")?;" << endl; + f_gen_ << indent() << "o_prot.write_i16(" + type_var + ")?;" << '\n'; return; case t_base_type::TYPE_I32: - f_gen_ << indent() << "o_prot.write_i32(" + type_var + ")?;" << endl; + f_gen_ << indent() << "o_prot.write_i32(" + type_var + ")?;" << '\n'; return; case t_base_type::TYPE_I64: - f_gen_ << indent() << "o_prot.write_i64(" + type_var + ")?;" << endl; + f_gen_ << indent() << "o_prot.write_i64(" + type_var + ")?;" << '\n'; return; case t_base_type::TYPE_DOUBLE: - f_gen_ << indent() << "o_prot.write_double(" + type_var + ".into())?;" << endl; + f_gen_ << indent() << "o_prot.write_double(" + type_var + ".into())?;" << '\n'; return; default: throw "compiler error: unhandled type"; @@ -1541,7 +1540,7 @@ void t_rs_generator::render_type_sync_write(const string& type_var, render_type_sync_write(type_var, type_var_is_ref, ttypedef->get_type()); return; } else if (ttype->is_enum() || ttype->is_struct() || ttype->is_xception()) { - f_gen_ << indent() << type_var + ".write_to_out_protocol(o_prot)?;" << endl; + f_gen_ << indent() << type_var + ".write_to_out_protocol(o_prot)?;" << '\n'; return; } else if (ttype->is_map()) { render_map_sync_write(type_var, type_var_is_ref, (t_map*)ttype); @@ -1566,15 +1565,15 @@ void t_rs_generator::render_list_sync_write(const string& list_var, << "&TListIdentifier::new(" << to_rust_field_type_enum(elem_type) << ", " << list_var << ".len() as i32" << ")" - << ")?;" << endl; + << ")?;" << '\n'; string ref(list_var_is_ref ? "" : "&"); - f_gen_ << indent() << "for e in " << ref << list_var << " {" << endl; + f_gen_ << indent() << "for e in " << ref << list_var << " {" << '\n'; indent_up(); render_type_sync_write(string_container_write_variable(elem_type, "e"), true, elem_type); indent_down(); - f_gen_ << indent() << "}" << endl; - f_gen_ << indent() << "o_prot.write_list_end()?;" << endl; + f_gen_ << indent() << "}" << '\n'; + f_gen_ << indent() << "o_prot.write_list_end()?;" << '\n'; } void t_rs_generator::render_set_sync_write(const string& set_var, @@ -1586,15 +1585,15 @@ void t_rs_generator::render_set_sync_write(const string& set_var, << "&TSetIdentifier::new(" << to_rust_field_type_enum(elem_type) << ", " << set_var << ".len() as i32" << ")" - << ")?;" << endl; + << ")?;" << '\n'; string ref(set_var_is_ref ? "" : "&"); - f_gen_ << indent() << "for e in " << ref << set_var << " {" << endl; + f_gen_ << indent() << "for e in " << ref << set_var << " {" << '\n'; indent_up(); render_type_sync_write(string_container_write_variable(elem_type, "e"), true, elem_type); indent_down(); - f_gen_ << indent() << "}" << endl; - f_gen_ << indent() << "o_prot.write_set_end()?;" << endl; + f_gen_ << indent() << "}" << '\n'; + f_gen_ << indent() << "o_prot.write_set_end()?;" << '\n'; } void t_rs_generator::render_map_sync_write(const string& map_var, @@ -1606,16 +1605,16 @@ void t_rs_generator::render_map_sync_write(const string& map_var, f_gen_ << indent() << "o_prot.write_map_begin(" << "&TMapIdentifier::new(" << to_rust_field_type_enum(key_type) << ", " << to_rust_field_type_enum(val_type) << ", " << map_var << ".len() as i32)" - << ")?;" << endl; + << ")?;" << '\n'; string ref(map_var_is_ref ? "" : "&"); - f_gen_ << indent() << "for (k, v) in " << ref << map_var << " {" << endl; + f_gen_ << indent() << "for (k, v) in " << ref << map_var << " {" << '\n'; indent_up(); render_type_sync_write(string_container_write_variable(key_type, "k"), true, key_type); render_type_sync_write(string_container_write_variable(val_type, "v"), true, val_type); indent_down(); - f_gen_ << indent() << "}" << endl; - f_gen_ << indent() << "o_prot.write_map_end()?;" << endl; + f_gen_ << indent() << "}" << '\n'; + f_gen_ << indent() << "o_prot.write_map_end()?;" << '\n'; } string t_rs_generator::string_container_write_variable(t_type* ttype, const string& base_var) { @@ -1651,11 +1650,11 @@ void t_rs_generator::render_struct_sync_read(const string& struct_name, t_rs_generator::e_struct_type struct_type) { f_gen_ << indent() << "fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result<" - << struct_name << "> {" << endl; + << struct_name << "> {" << '\n'; indent_up(); - f_gen_ << indent() << "i_prot.read_struct_begin()?;" << endl; + f_gen_ << indent() << "i_prot.read_struct_begin()?;" << '\n'; // create temporary variables: one for each field in the struct const vector members = tstruct->get_sorted_members(); @@ -1671,55 +1670,55 @@ void t_rs_generator::render_struct_sync_read(const string& struct_name, } else { f_gen_ << "None;"; } - f_gen_ << endl; + f_gen_ << '\n'; } // now loop through the fields we've received - f_gen_ << indent() << "loop {" << endl; // start loop + f_gen_ << indent() << "loop {" << '\n'; // start loop indent_up(); // break out if you've found the Stop field - f_gen_ << indent() << "let field_ident = i_prot.read_field_begin()?;" << endl; - f_gen_ << indent() << "if field_ident.field_type == TType::Stop {" << endl; + f_gen_ << indent() << "let field_ident = i_prot.read_field_begin()?;" << '\n'; + f_gen_ << indent() << "if field_ident.field_type == TType::Stop {" << '\n'; indent_up(); - f_gen_ << indent() << "break;" << endl; + f_gen_ << indent() << "break;" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; // now read all the fields found // avoid clippy::match_single_binding if (members.empty()) { - f_gen_ << indent() << "i_prot.skip(field_ident.field_type)?;" << endl; + f_gen_ << indent() << "i_prot.skip(field_ident.field_type)?;" << '\n'; } else { - f_gen_ << indent() << "let field_id = field_id(&field_ident)?;" << endl; - f_gen_ << indent() << "match field_id {" << endl; // start match + f_gen_ << indent() << "let field_id = field_id(&field_ident)?;" << '\n'; + f_gen_ << indent() << "match field_id {" << '\n'; // start match indent_up(); for (members_iter = members.begin(); members_iter != members.end(); ++members_iter) { t_field* tfield = (*members_iter); - f_gen_ << indent() << rust_safe_field_id(tfield->get_key()) << " => {" << endl; + f_gen_ << indent() << rust_safe_field_id(tfield->get_key()) << " => {" << '\n'; indent_up(); render_type_sync_read("val", tfield->get_type()); - f_gen_ << indent() << struct_field_read_temp_variable(tfield) << " = Some(val);" << endl; + f_gen_ << indent() << struct_field_read_temp_variable(tfield) << " = Some(val);" << '\n'; indent_down(); - f_gen_ << indent() << "}," << endl; + f_gen_ << indent() << "}," << '\n'; } // default case (skip fields) - f_gen_ << indent() << "_ => {" << endl; + f_gen_ << indent() << "_ => {" << '\n'; indent_up(); - f_gen_ << indent() << "i_prot.skip(field_ident.field_type)?;" << endl; + f_gen_ << indent() << "i_prot.skip(field_ident.field_type)?;" << '\n'; indent_down(); - f_gen_ << indent() << "}," << endl; + f_gen_ << indent() << "}," << '\n'; indent_down(); - f_gen_ << indent() << "};" << endl; // finish match + f_gen_ << indent() << "};" << '\n'; // finish match } - f_gen_ << indent() << "i_prot.read_field_end()?;" << endl; + f_gen_ << indent() << "i_prot.read_field_end()?;" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; // finish loop - f_gen_ << indent() << "i_prot.read_struct_end()?;" << endl; // read message footer from the wire + f_gen_ << indent() << "}" << '\n'; // finish loop + f_gen_ << indent() << "i_prot.read_struct_end()?;" << '\n'; // read message footer from the wire // verify that all required fields exist for (members_iter = members.begin(); members_iter != members.end(); ++members_iter) { @@ -1729,15 +1728,15 @@ void t_rs_generator::render_struct_sync_read(const string& struct_name, f_gen_ << indent() << "verify_required_field_exists(" << "\"" << struct_name << "." << rust_field_name(tfield) << "\"" << ", " - << "&" << struct_field_read_temp_variable(tfield) << ")?;" << endl; + << "&" << struct_field_read_temp_variable(tfield) << ")?;" << '\n'; } } // construct the struct if (members.size() == 0) { - f_gen_ << indent() << "let ret = " << struct_name << " {};" << endl; + f_gen_ << indent() << "let ret = " << struct_name << " {};" << '\n'; } else { - f_gen_ << indent() << "let ret = " << struct_name << " {" << endl; + f_gen_ << indent() << "let ret = " << struct_name << " {" << '\n'; indent_up(); for (members_iter = members.begin(); members_iter != members.end(); ++members_iter) { @@ -1746,109 +1745,109 @@ void t_rs_generator::render_struct_sync_read(const string& struct_name, string field_name(rust_field_name(tfield)); string field_key = struct_field_read_temp_variable(tfield); if (is_optional(req)) { - f_gen_ << indent() << field_name << ": " << field_key << "," << endl; + f_gen_ << indent() << field_name << ": " << field_key << "," << '\n'; } else { f_gen_ << indent() << field_name << ": " << field_key << ".expect(\"auto-generated code should have checked for presence of required " "fields\")" - << "," << endl; + << "," << '\n'; } } indent_down(); - f_gen_ << indent() << "};" << endl; + f_gen_ << indent() << "};" << '\n'; } // return the constructed value - f_gen_ << indent() << "Ok(ret)" << endl; + f_gen_ << indent() << "Ok(ret)" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; } void t_rs_generator::render_union_sync_read(const string& union_name, t_struct* tstruct) { f_gen_ << indent() << "fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result<" - << union_name << "> {" << endl; + << union_name << "> {" << '\n'; indent_up(); // create temporary variables to hold the // completed union as well as a count of fields read - f_gen_ << indent() << "let mut ret: Option<" << union_name << "> = None;" << endl; - f_gen_ << indent() << "let mut received_field_count = 0;" << endl; + f_gen_ << indent() << "let mut ret: Option<" << union_name << "> = None;" << '\n'; + f_gen_ << indent() << "let mut received_field_count = 0;" << '\n'; // read the struct preamble - f_gen_ << indent() << "i_prot.read_struct_begin()?;" << endl; + f_gen_ << indent() << "i_prot.read_struct_begin()?;" << '\n'; // now loop through the fields we've received - f_gen_ << indent() << "loop {" << endl; // start loop + f_gen_ << indent() << "loop {" << '\n'; // start loop indent_up(); // break out if you've found the Stop field - f_gen_ << indent() << "let field_ident = i_prot.read_field_begin()?;" << endl; - f_gen_ << indent() << "if field_ident.field_type == TType::Stop {" << endl; + f_gen_ << indent() << "let field_ident = i_prot.read_field_begin()?;" << '\n'; + f_gen_ << indent() << "if field_ident.field_type == TType::Stop {" << '\n'; indent_up(); - f_gen_ << indent() << "break;" << endl; + f_gen_ << indent() << "break;" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; // now read all the fields found - f_gen_ << indent() << "let field_id = field_id(&field_ident)?;" << endl; - f_gen_ << indent() << "match field_id {" << endl; // start match + f_gen_ << indent() << "let field_id = field_id(&field_ident)?;" << '\n'; + f_gen_ << indent() << "match field_id {" << '\n'; // start match indent_up(); const vector members = tstruct->get_sorted_members(); vector::const_iterator members_iter; for (members_iter = members.begin(); members_iter != members.end(); ++members_iter) { t_field* member = (*members_iter); - f_gen_ << indent() << rust_safe_field_id(member->get_key()) << " => {" << endl; + f_gen_ << indent() << rust_safe_field_id(member->get_key()) << " => {" << '\n'; indent_up(); render_type_sync_read("val", member->get_type()); - f_gen_ << indent() << "if ret.is_none() {" << endl; + f_gen_ << indent() << "if ret.is_none() {" << '\n'; indent_up(); f_gen_ << indent() << "ret = Some(" << union_name << "::" << rust_union_field_name(member) - << "(val));" << endl; + << "(val));" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; - f_gen_ << indent() << "received_field_count += 1;" << endl; + f_gen_ << indent() << "}" << '\n'; + f_gen_ << indent() << "received_field_count += 1;" << '\n'; indent_down(); - f_gen_ << indent() << "}," << endl; + f_gen_ << indent() << "}," << '\n'; } // default case (skip fields) - f_gen_ << indent() << "_ => {" << endl; + f_gen_ << indent() << "_ => {" << '\n'; indent_up(); - f_gen_ << indent() << "i_prot.skip(field_ident.field_type)?;" << endl; - f_gen_ << indent() << "received_field_count += 1;" << endl; + f_gen_ << indent() << "i_prot.skip(field_ident.field_type)?;" << '\n'; + f_gen_ << indent() << "received_field_count += 1;" << '\n'; indent_down(); - f_gen_ << indent() << "}," << endl; + f_gen_ << indent() << "}," << '\n'; indent_down(); - f_gen_ << indent() << "};" << endl; // finish match - f_gen_ << indent() << "i_prot.read_field_end()?;" << endl; + f_gen_ << indent() << "};" << '\n'; // finish match + f_gen_ << indent() << "i_prot.read_field_end()?;" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; // finish loop - f_gen_ << indent() << "i_prot.read_struct_end()?;" << endl; // finish reading message from wire + f_gen_ << indent() << "}" << '\n'; // finish loop + f_gen_ << indent() << "i_prot.read_struct_end()?;" << '\n'; // finish reading message from wire // return the value or an error - f_gen_ << indent() << "if received_field_count == 0 {" << endl; + f_gen_ << indent() << "if received_field_count == 0 {" << '\n'; indent_up(); render_thrift_error("Protocol", "ProtocolError", "ProtocolErrorKind::InvalidData", "\"received empty union from remote " + union_name + "\""); indent_down(); - f_gen_ << indent() << "} else if received_field_count > 1 {" << endl; + f_gen_ << indent() << "} else if received_field_count > 1 {" << '\n'; indent_up(); render_thrift_error("Protocol", "ProtocolError", "ProtocolErrorKind::InvalidData", "\"received multiple fields for union from remote " + union_name + "\""); indent_down(); - f_gen_ << indent() << "} else {" << endl; + f_gen_ << indent() << "} else {" << '\n'; indent_up(); - f_gen_ << indent() << "Ok(ret.expect(\"return value should have been constructed\"))" << endl; + f_gen_ << indent() << "Ok(ret.expect(\"return value should have been constructed\"))" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; } // Construct the rust representation of all supported types from the wire. @@ -1860,32 +1859,32 @@ void t_rs_generator::render_type_sync_read(const string& type_var, t_type* ttype throw "cannot read field of type TYPE_VOID from input protocol"; case t_base_type::TYPE_STRING: if (tbase_type->is_binary()) { - f_gen_ << indent() << "let " << type_var << " = i_prot.read_bytes()?;" << endl; + f_gen_ << indent() << "let " << type_var << " = i_prot.read_bytes()?;" << '\n'; } else { - f_gen_ << indent() << "let " << type_var << " = i_prot.read_string()?;" << endl; + f_gen_ << indent() << "let " << type_var << " = i_prot.read_string()?;" << '\n'; } return; case t_base_type::TYPE_UUID: - f_gen_ << indent() << "let " << type_var << " = i_prot.read_uuid()?;" << endl; + f_gen_ << indent() << "let " << type_var << " = i_prot.read_uuid()?;" << '\n'; return; case t_base_type::TYPE_BOOL: - f_gen_ << indent() << "let " << type_var << " = i_prot.read_bool()?;" << endl; + f_gen_ << indent() << "let " << type_var << " = i_prot.read_bool()?;" << '\n'; return; case t_base_type::TYPE_I8: - f_gen_ << indent() << "let " << type_var << " = i_prot.read_i8()?;" << endl; + f_gen_ << indent() << "let " << type_var << " = i_prot.read_i8()?;" << '\n'; return; case t_base_type::TYPE_I16: - f_gen_ << indent() << "let " << type_var << " = i_prot.read_i16()?;" << endl; + f_gen_ << indent() << "let " << type_var << " = i_prot.read_i16()?;" << '\n'; return; case t_base_type::TYPE_I32: - f_gen_ << indent() << "let " << type_var << " = i_prot.read_i32()?;" << endl; + f_gen_ << indent() << "let " << type_var << " = i_prot.read_i32()?;" << '\n'; return; case t_base_type::TYPE_I64: - f_gen_ << indent() << "let " << type_var << " = i_prot.read_i64()?;" << endl; + f_gen_ << indent() << "let " << type_var << " = i_prot.read_i64()?;" << '\n'; return; case t_base_type::TYPE_DOUBLE: f_gen_ << indent() << "let " << type_var << " = OrderedFloat::from(i_prot.read_double()?);" - << endl; + << '\n'; return; default: throw "compiler error: unhandled type"; @@ -1905,7 +1904,7 @@ void t_rs_generator::render_type_sync_read(const string& type_var, t_type* ttype } else if (ttype->is_enum() || ttype->is_struct() || ttype->is_xception()) { string read_call(to_rust_type(ttype) + "::read_from_in_protocol(i_prot)?"); read_call = is_boxed ? "Box::new(" + read_call + ")" : read_call; - f_gen_ << indent() << "let " << type_var << " = " << read_call << ";" << endl; + f_gen_ << indent() << "let " << type_var << " = " << read_call << ";" << '\n'; return; } else if (ttype->is_map()) { render_map_sync_read((t_map*)ttype, type_var); @@ -1925,42 +1924,42 @@ void t_rs_generator::render_type_sync_read(const string& type_var, t_type* ttype void t_rs_generator::render_list_sync_read(t_list* tlist, const string& list_var) { t_type* elem_type = tlist->get_elem_type(); - f_gen_ << indent() << "let list_ident = i_prot.read_list_begin()?;" << endl; + f_gen_ << indent() << "let list_ident = i_prot.read_list_begin()?;" << '\n'; f_gen_ << indent() << "let mut " << list_var << ": " << to_rust_type((t_type*)tlist) - << " = Vec::with_capacity(list_ident.size as usize);" << endl; - f_gen_ << indent() << "for _ in 0..list_ident.size {" << endl; + << " = Vec::with_capacity(list_ident.size as usize);" << '\n'; + f_gen_ << indent() << "for _ in 0..list_ident.size {" << '\n'; indent_up(); string list_elem_var = tmp("list_elem_"); render_type_sync_read(list_elem_var, elem_type); - f_gen_ << indent() << list_var << ".push(" << list_elem_var << ");" << endl; + f_gen_ << indent() << list_var << ".push(" << list_elem_var << ");" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; - f_gen_ << indent() << "i_prot.read_list_end()?;" << endl; + f_gen_ << indent() << "}" << '\n'; + f_gen_ << indent() << "i_prot.read_list_end()?;" << '\n'; } // Construct the rust representation of a set from the wire. void t_rs_generator::render_set_sync_read(t_set* tset, const string& set_var) { t_type* elem_type = tset->get_elem_type(); - f_gen_ << indent() << "let set_ident = i_prot.read_set_begin()?;" << endl; + f_gen_ << indent() << "let set_ident = i_prot.read_set_begin()?;" << '\n'; f_gen_ << indent() << "let mut " << set_var << ": " << to_rust_type((t_type*)tset) - << " = BTreeSet::new();" << endl; - f_gen_ << indent() << "for _ in 0..set_ident.size {" << endl; + << " = BTreeSet::new();" << '\n'; + f_gen_ << indent() << "for _ in 0..set_ident.size {" << '\n'; indent_up(); string set_elem_var = tmp("set_elem_"); render_type_sync_read(set_elem_var, elem_type); - f_gen_ << indent() << set_var << ".insert(" << set_elem_var << ");" << endl; + f_gen_ << indent() << set_var << ".insert(" << set_elem_var << ");" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; - f_gen_ << indent() << "i_prot.read_set_end()?;" << endl; + f_gen_ << indent() << "}" << '\n'; + f_gen_ << indent() << "i_prot.read_set_end()?;" << '\n'; } // Construct the rust representation of a map from the wire. @@ -1968,10 +1967,10 @@ void t_rs_generator::render_map_sync_read(t_map* tmap, const string& map_var) { t_type* key_type = tmap->get_key_type(); t_type* val_type = tmap->get_val_type(); - f_gen_ << indent() << "let map_ident = i_prot.read_map_begin()?;" << endl; + f_gen_ << indent() << "let map_ident = i_prot.read_map_begin()?;" << '\n'; f_gen_ << indent() << "let mut " << map_var << ": " << to_rust_type((t_type*)tmap) - << " = BTreeMap::new();" << endl; - f_gen_ << indent() << "for _ in 0..map_ident.size {" << endl; + << " = BTreeMap::new();" << '\n'; + f_gen_ << indent() << "for _ in 0..map_ident.size {" << '\n'; indent_up(); @@ -1980,12 +1979,12 @@ void t_rs_generator::render_map_sync_read(t_map* tmap, const string& map_var) { string val_elem_var = tmp("map_val_"); render_type_sync_read(val_elem_var, val_type); f_gen_ << indent() << map_var << ".insert(" << key_elem_var << ", " << val_elem_var << ");" - << endl; + << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; - f_gen_ << indent() << "i_prot.read_map_end()?;" << endl; + f_gen_ << indent() << "}" << '\n'; + f_gen_ << indent() << "i_prot.read_map_end()?;" << '\n'; } string t_rs_generator::struct_field_read_temp_variable(t_field* tfield) { @@ -2036,7 +2035,7 @@ void t_rs_generator::render_sync_client(t_service* tservice) { render_sync_client_definition_and_impl(client_impl_name); render_sync_client_tthriftclient_impl(client_impl_name); render_sync_client_marker_trait_impls(tservice, client_impl_name); - f_gen_ << endl; + f_gen_ << '\n'; render_sync_client_process_impl(tservice); } @@ -2048,7 +2047,7 @@ void t_rs_generator::render_sync_client_trait(t_service* tservice) { } render_rustdoc((t_doc*)tservice); - f_gen_ << "pub trait " << rust_sync_client_trait_name(tservice) << extension << " {" << endl; + f_gen_ << "pub trait " << rust_sync_client_trait_name(tservice) << extension << " {" << '\n'; indent_up(); const std::vector functions = tservice->get_functions(); @@ -2060,25 +2059,25 @@ void t_rs_generator::render_sync_client_trait(t_service* tservice) { string func_return = to_rust_type(tfunc->get_returntype()); render_rustdoc((t_doc*)tfunc); f_gen_ << indent() << "fn " << func_name << func_args << " -> thrift::Result<" << func_return - << ">;" << endl; + << ">;" << '\n'; } indent_down(); - f_gen_ << indent() << "}" << endl; - f_gen_ << endl; + f_gen_ << indent() << "}" << '\n'; + f_gen_ << '\n'; } void t_rs_generator::render_sync_client_marker_trait(t_service* tservice) { f_gen_ << indent() << "pub trait " << rust_sync_client_marker_trait_name(tservice) << " {}" - << endl; - f_gen_ << endl; + << '\n'; + f_gen_ << '\n'; } void t_rs_generator::render_sync_client_marker_trait_impls(t_service* tservice, const string& impl_struct_name) { f_gen_ << indent() << "impl " << SYNC_CLIENT_GENERIC_BOUND_VARS << " " << rust_namespace(tservice) << rust_sync_client_marker_trait_name(tservice) << " for " << impl_struct_name - << SYNC_CLIENT_GENERIC_BOUND_VARS << " " << SYNC_CLIENT_GENERIC_BOUNDS << " {}" << endl; + << SYNC_CLIENT_GENERIC_BOUND_VARS << " " << SYNC_CLIENT_GENERIC_BOUNDS << " {}" << '\n'; t_service* extends = tservice->get_extends(); if (extends) { @@ -2090,64 +2089,64 @@ void t_rs_generator::render_sync_client_definition_and_impl(const string& client // render the definition for the client struct f_gen_ << "pub struct " << client_impl_name << SYNC_CLIENT_GENERIC_BOUND_VARS << " " - << SYNC_CLIENT_GENERIC_BOUNDS << " {" << endl; + << SYNC_CLIENT_GENERIC_BOUNDS << " {" << '\n'; indent_up(); - f_gen_ << indent() << "_i_prot: IP," << endl; - f_gen_ << indent() << "_o_prot: OP," << endl; - f_gen_ << indent() << "_sequence_number: i32," << endl; + f_gen_ << indent() << "_i_prot: IP," << '\n'; + f_gen_ << indent() << "_o_prot: OP," << '\n'; + f_gen_ << indent() << "_sequence_number: i32," << '\n'; indent_down(); - f_gen_ << "}" << endl; - f_gen_ << endl; + f_gen_ << "}" << '\n'; + f_gen_ << '\n'; // render the struct implementation // this includes the new() function as well as the helper send/recv methods for each service call f_gen_ << "impl " << SYNC_CLIENT_GENERIC_BOUND_VARS << " " << client_impl_name - << SYNC_CLIENT_GENERIC_BOUND_VARS << " " << SYNC_CLIENT_GENERIC_BOUNDS << " {" << endl; + << SYNC_CLIENT_GENERIC_BOUND_VARS << " " << SYNC_CLIENT_GENERIC_BOUNDS << " {" << '\n'; indent_up(); render_sync_client_lifecycle_functions(client_impl_name); indent_down(); - f_gen_ << "}" << endl; - f_gen_ << endl; + f_gen_ << "}" << '\n'; + f_gen_ << '\n'; } void t_rs_generator::render_sync_client_lifecycle_functions(const string& client_struct) { f_gen_ << indent() << "pub fn new(input_protocol: IP, output_protocol: OP) -> " << client_struct - << SYNC_CLIENT_GENERIC_BOUND_VARS << " {" << endl; + << SYNC_CLIENT_GENERIC_BOUND_VARS << " {" << '\n'; indent_up(); f_gen_ << indent() << client_struct - << " { _i_prot: input_protocol, _o_prot: output_protocol, _sequence_number: 0 }" << endl; + << " { _i_prot: input_protocol, _o_prot: output_protocol, _sequence_number: 0 }" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; } void t_rs_generator::render_sync_client_tthriftclient_impl(const string& client_impl_name) { f_gen_ << indent() << "impl " << SYNC_CLIENT_GENERIC_BOUND_VARS << " TThriftClient for " << client_impl_name << SYNC_CLIENT_GENERIC_BOUND_VARS << " " << SYNC_CLIENT_GENERIC_BOUNDS - << " {" << endl; + << " {" << '\n'; indent_up(); f_gen_ << indent() << "fn i_prot_mut(&mut self) -> &mut dyn TInputProtocol { &mut self._i_prot }" - << endl; + << '\n'; f_gen_ << indent() << "fn o_prot_mut(&mut self) -> &mut dyn TOutputProtocol { &mut self._o_prot }" - << endl; - f_gen_ << indent() << "fn sequence_number(&self) -> i32 { self._sequence_number }" << endl; + << '\n'; + f_gen_ << indent() << "fn sequence_number(&self) -> i32 { self._sequence_number }" << '\n'; f_gen_ << indent() << "fn increment_sequence_number(&mut self) -> i32 { self._sequence_number += 1; " "self._sequence_number }" - << endl; + << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; - f_gen_ << endl; + f_gen_ << indent() << "}" << '\n'; + f_gen_ << '\n'; } void t_rs_generator::render_sync_client_process_impl(t_service* tservice) { string marker_extension = "" + sync_client_marker_traits_for_extension(tservice); f_gen_ << "impl " << rust_sync_client_trait_name(tservice) << " for C {" << endl; + << marker_extension << "> " << rust_sync_client_trait_name(tservice) << " for C {" << '\n'; indent_up(); const std::vector functions = tservice->get_functions(); @@ -2158,8 +2157,8 @@ void t_rs_generator::render_sync_client_process_impl(t_service* tservice) { } indent_down(); - f_gen_ << "}" << endl; - f_gen_ << endl; + f_gen_ << "}" << '\n'; + f_gen_ << '\n'; } string t_rs_generator::sync_client_marker_traits_for_extension(t_service* tservice) { @@ -2182,35 +2181,35 @@ void t_rs_generator::render_sync_send_recv_wrapper(t_function* tfunc) { string func_return = to_rust_type(tfunc->get_returntype()); f_gen_ << indent() << "fn " << func_name << func_decl_args << " -> thrift::Result<" << func_return - << "> {" << endl; + << "> {" << '\n'; indent_up(); - f_gen_ << indent() << "(" << endl; + f_gen_ << indent() << "(" << '\n'; indent_up(); render_sync_send(tfunc); indent_down(); - f_gen_ << indent() << ")?;" << endl; + f_gen_ << indent() << ")?;" << '\n'; if (tfunc->is_oneway()) { - f_gen_ << indent() << "Ok(())" << endl; + f_gen_ << indent() << "Ok(())" << '\n'; } else { render_sync_recv(tfunc); } indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; } void t_rs_generator::render_sync_send(t_function* tfunc) { - f_gen_ << indent() << "{" << endl; + f_gen_ << indent() << "{" << '\n'; indent_up(); // increment the sequence number and generate the call header string message_type = tfunc->is_oneway() ? "TMessageType::OneWay" : "TMessageType::Call"; - f_gen_ << indent() << "self.increment_sequence_number();" << endl; + f_gen_ << indent() << "self.increment_sequence_number();" << '\n'; f_gen_ << indent() << "let message_ident = " << "TMessageIdentifier::new(\"" << tfunc->get_name() << "\", " // note: use *original* name << message_type << ", " - << "self.sequence_number());" << endl; + << "self.sequence_number());" << '\n'; // pack the arguments into the containing struct that we'll write out over the wire // note that this struct is generated even if we have 0 args ostringstream struct_definition; @@ -2226,50 +2225,50 @@ void t_rs_generator::render_sync_send(t_function* tfunc) { struct_fields = struct_fields.substr(0, struct_fields.size() - 2); // strip trailing comma } f_gen_ << indent() << "let call_args = " << service_call_args_struct_name(tfunc) << " { " - << struct_fields << " };" << endl; + << struct_fields << " };" << '\n'; // write everything over the wire - f_gen_ << indent() << "self.o_prot_mut().write_message_begin(&message_ident)?;" << endl; + f_gen_ << indent() << "self.o_prot_mut().write_message_begin(&message_ident)?;" << '\n'; f_gen_ << indent() << "call_args.write_to_out_protocol(self.o_prot_mut())?;" - << endl; // written even if we have 0 args - f_gen_ << indent() << "self.o_prot_mut().write_message_end()?;" << endl; - f_gen_ << indent() << "self.o_prot_mut().flush()" << endl; + << '\n'; // written even if we have 0 args + f_gen_ << indent() << "self.o_prot_mut().write_message_end()?;" << '\n'; + f_gen_ << indent() << "self.o_prot_mut().flush()" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; } void t_rs_generator::render_sync_recv(t_function* tfunc) { - f_gen_ << indent() << "{" << endl; + f_gen_ << indent() << "{" << '\n'; indent_up(); - f_gen_ << indent() << "let message_ident = self.i_prot_mut().read_message_begin()?;" << endl; + f_gen_ << indent() << "let message_ident = self.i_prot_mut().read_message_begin()?;" << '\n'; f_gen_ << indent() << "verify_expected_sequence_number(self.sequence_number(), message_ident.sequence_number)?;" - << endl; + << '\n'; f_gen_ << indent() << "verify_expected_service_call(\"" << tfunc->get_name() - << "\", &message_ident.name)?;" << endl; // note: use *original* name + << "\", &message_ident.name)?;" << '\n'; // note: use *original* name // FIXME: replace with a "try" block - f_gen_ << indent() << "if message_ident.message_type == TMessageType::Exception {" << endl; + f_gen_ << indent() << "if message_ident.message_type == TMessageType::Exception {" << '\n'; indent_up(); f_gen_ << indent() << "let remote_error = " "thrift::Error::read_application_error_from_in_protocol(self.i_prot_mut())?;" - << endl; - f_gen_ << indent() << "self.i_prot_mut().read_message_end()?;" << endl; - f_gen_ << indent() << "return Err(thrift::Error::Application(remote_error))" << endl; + << '\n'; + f_gen_ << indent() << "self.i_prot_mut().read_message_end()?;" << '\n'; + f_gen_ << indent() << "return Err(thrift::Error::Application(remote_error))" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; f_gen_ << indent() << "verify_expected_message_type(TMessageType::Reply, message_ident.message_type)?;" - << endl; + << '\n'; f_gen_ << indent() << "let result = " << service_call_result_struct_name(tfunc) - << "::read_from_in_protocol(self.i_prot_mut())?;" << endl; - f_gen_ << indent() << "self.i_prot_mut().read_message_end()?;" << endl; - f_gen_ << indent() << "result.ok_or()" << endl; + << "::read_from_in_protocol(self.i_prot_mut())?;" << '\n'; + f_gen_ << indent() << "self.i_prot_mut().read_message_end()?;" << '\n'; + f_gen_ << indent() << "result.ok_or()" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; } string t_rs_generator::rust_sync_service_call_declaration(t_function* tfunc, bool self_is_mutable) { @@ -2400,7 +2399,7 @@ void t_rs_generator::render_sync_handler_trait(t_service* tservice) { std::vector::const_iterator func_iter; render_rustdoc((t_doc*)tservice); - f_gen_ << "pub trait " << rust_sync_handler_trait_name(tservice) << extension << " {" << endl; + f_gen_ << "pub trait " << rust_sync_handler_trait_name(tservice) << extension << " {" << '\n'; indent_up(); for (func_iter = functions.begin(); func_iter != functions.end(); ++func_iter) { t_function* tfunc = (*func_iter); @@ -2409,11 +2408,11 @@ void t_rs_generator::render_sync_handler_trait(t_service* tservice) { string func_return = to_rust_type(tfunc->get_returntype()); render_rustdoc((t_doc*)tfunc); f_gen_ << indent() << "fn " << func_name << func_args << " -> thrift::Result<" << func_return - << ">;" << endl; + << ">;" << '\n'; } indent_down(); - f_gen_ << indent() << "}" << endl; - f_gen_ << endl; + f_gen_ << indent() << "}" << '\n'; + f_gen_ << '\n'; } void t_rs_generator::render_sync_processor_definition_and_impl(t_service* tservice) { @@ -2422,36 +2421,36 @@ void t_rs_generator::render_sync_processor_definition_and_impl(t_service* tservi // struct f_gen_ << indent() << "pub struct " << service_processor_name << " {" << endl; + << "> {" << '\n'; indent_up(); - f_gen_ << indent() << "handler: H," << endl; + f_gen_ << indent() << "handler: H," << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; - f_gen_ << endl; + f_gen_ << indent() << "}" << '\n'; + f_gen_ << '\n'; // delegating impl f_gen_ << indent() << "impl " << service_processor_name - << " {" << endl; + << " {" << '\n'; indent_up(); - f_gen_ << indent() << "pub fn new(handler: H) -> " << service_processor_name << " {" << endl; + f_gen_ << indent() << "pub fn new(handler: H) -> " << service_processor_name << " {" << '\n'; indent_up(); - f_gen_ << indent() << service_processor_name << " {" << endl; + f_gen_ << indent() << service_processor_name << " {" << '\n'; indent_up(); - f_gen_ << indent() << "handler," << endl; + f_gen_ << indent() << "handler," << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; render_sync_process_delegation_functions(tservice); indent_down(); - f_gen_ << indent() << "}" << endl; - f_gen_ << endl; + f_gen_ << indent() << "}" << '\n'; + f_gen_ << '\n'; // actual impl string service_actual_processor_name = rust_sync_processor_impl_name(tservice); - f_gen_ << indent() << "pub struct " << service_actual_processor_name << ";" << endl; - f_gen_ << endl; - f_gen_ << indent() << "impl " << service_actual_processor_name << " {" << endl; + f_gen_ << indent() << "pub struct " << service_actual_processor_name << ";" << '\n'; + f_gen_ << '\n'; + f_gen_ << indent() << "impl " << service_actual_processor_name << " {" << '\n'; indent_up(); vector functions = tservice->get_functions(); @@ -2462,44 +2461,44 @@ void t_rs_generator::render_sync_processor_definition_and_impl(t_service* tservi } indent_down(); - f_gen_ << indent() << "}" << endl; - f_gen_ << endl; + f_gen_ << indent() << "}" << '\n'; + f_gen_ << '\n'; // processor impl f_gen_ << indent() << "impl TProcessor for " - << service_processor_name << " {" << endl; + << service_processor_name << " {" << '\n'; indent_up(); f_gen_ << indent() << "fn process(&self, i_prot: &mut dyn TInputProtocol, o_prot: &mut dyn TOutputProtocol) " "-> thrift::Result<()> {" - << endl; + << '\n'; indent_up(); - f_gen_ << indent() << "let message_ident = i_prot.read_message_begin()?;" << endl; + f_gen_ << indent() << "let message_ident = i_prot.read_message_begin()?;" << '\n'; f_gen_ << indent() << "let res = match &*message_ident.name {" - << endl; // [sigh] explicit deref coercion + << '\n'; // [sigh] explicit deref coercion indent_up(); render_process_match_statements(tservice); - f_gen_ << indent() << "method => {" << endl; + f_gen_ << indent() << "method => {" << '\n'; indent_up(); render_thrift_error("Application", "ApplicationError", "ApplicationErrorKind::UnknownMethod", "format!(\"unknown method {}\", method)"); indent_down(); - f_gen_ << indent() << "}," << endl; + f_gen_ << indent() << "}," << '\n'; indent_down(); - f_gen_ << indent() << "};" << endl; + f_gen_ << indent() << "};" << '\n'; f_gen_ << indent() << "thrift::server::handle_process_result(&message_ident, res, o_prot)" - << endl; + << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; - f_gen_ << endl; + f_gen_ << indent() << "}" << '\n'; + f_gen_ << '\n'; } void t_rs_generator::render_sync_process_delegation_functions(t_service* tservice) { @@ -2514,7 +2513,7 @@ void t_rs_generator::render_sync_process_delegation_functions(t_service* tservic << "incoming_sequence_number: i32, " << "i_prot: &mut dyn TInputProtocol, " << "o_prot: &mut dyn TOutputProtocol) " - << "-> thrift::Result<()> {" << endl; + << "-> thrift::Result<()> {" << '\n'; indent_up(); f_gen_ << indent() << actual_processor << "::" << function_name << "(" @@ -2522,10 +2521,10 @@ void t_rs_generator::render_sync_process_delegation_functions(t_service* tservic << "incoming_sequence_number, " << "i_prot, " << "o_prot" - << ")" << endl; + << ")" << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; } t_service* extends = tservice->get_extends(); @@ -2540,12 +2539,12 @@ void t_rs_generator::render_process_match_statements(t_service* tservice) { for (func_iter = functions.begin(); func_iter != functions.end(); ++func_iter) { t_function* tfunc = (*func_iter); f_gen_ << indent() << "\"" << tfunc->get_name() << "\"" - << " => {" << endl; // note: use *original* name + << " => {" << '\n'; // note: use *original* name indent_up(); f_gen_ << indent() << "self.process_" << rust_snake_case(tfunc->get_name()) - << "(message_ident.sequence_number, i_prot, o_prot)" << endl; + << "(message_ident.sequence_number, i_prot, o_prot)" << '\n'; indent_down(); - f_gen_ << indent() << "}," << endl; + f_gen_ << indent() << "}," << '\n'; } t_service* extends = tservice->get_extends(); @@ -2568,90 +2567,90 @@ void t_rs_generator::render_sync_process_function(t_function* tfunc, const strin << "(handler: &H, " << sequence_number_param << ": i32, " << "i_prot: &mut dyn TInputProtocol, " << output_protocol_param << ": &mut dyn TOutputProtocol) " - << "-> thrift::Result<()> {" << endl; + << "-> thrift::Result<()> {" << '\n'; indent_up(); // *always* read arguments from the input protocol f_gen_ << indent() << "let " << (has_non_void_args(tfunc) ? "args" : "_") << " = " - << service_call_args_struct_name(tfunc) << "::read_from_in_protocol(i_prot)?;" << endl; + << service_call_args_struct_name(tfunc) << "::read_from_in_protocol(i_prot)?;" << '\n'; f_gen_ << indent() << "match handler." << service_call_handler_function_name(tfunc) - << rust_sync_service_call_invocation(tfunc, "args.") << " {" << endl; // start match + << rust_sync_service_call_invocation(tfunc, "args.") << " {" << '\n'; // start match indent_up(); // handler succeeded string handler_return_variable = tfunc->is_oneway() || tfunc->get_returntype()->is_void() ? "_" : "handler_return"; - f_gen_ << indent() << "Ok(" << handler_return_variable << ") => {" << endl; + f_gen_ << indent() << "Ok(" << handler_return_variable << ") => {" << '\n'; indent_up(); render_sync_handler_succeeded(tfunc); indent_down(); - f_gen_ << indent() << "}," << endl; + f_gen_ << indent() << "}," << '\n'; // handler failed - f_gen_ << indent() << "Err(e) => {" << endl; + f_gen_ << indent() << "Err(e) => {" << '\n'; indent_up(); render_sync_handler_failed(tfunc); indent_down(); - f_gen_ << indent() << "}," << endl; + f_gen_ << indent() << "}," << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; // end match + f_gen_ << indent() << "}" << '\n'; // end match indent_down(); - f_gen_ << indent() << "}" << endl; // end function + f_gen_ << indent() << "}" << '\n'; // end function } void t_rs_generator::render_sync_handler_succeeded(t_function* tfunc) { if (tfunc->is_oneway()) { - f_gen_ << indent() << "Ok(())" << endl; + f_gen_ << indent() << "Ok(())" << '\n'; } else { f_gen_ << indent() << "let message_ident = TMessageIdentifier::new(" << "\"" << tfunc->get_name() << "\", " // note: use *original* name << "TMessageType::Reply, " - << "incoming_sequence_number);" << endl; - f_gen_ << indent() << "o_prot.write_message_begin(&message_ident)?;" << endl; - f_gen_ << indent() << "let ret = " << handler_successful_return_struct(tfunc) << ";" << endl; - f_gen_ << indent() << "ret.write_to_out_protocol(o_prot)?;" << endl; - f_gen_ << indent() << "o_prot.write_message_end()?;" << endl; - f_gen_ << indent() << "o_prot.flush()" << endl; + << "incoming_sequence_number);" << '\n'; + f_gen_ << indent() << "o_prot.write_message_begin(&message_ident)?;" << '\n'; + f_gen_ << indent() << "let ret = " << handler_successful_return_struct(tfunc) << ";" << '\n'; + f_gen_ << indent() << "ret.write_to_out_protocol(o_prot)?;" << '\n'; + f_gen_ << indent() << "o_prot.write_message_end()?;" << '\n'; + f_gen_ << indent() << "o_prot.flush()" << '\n'; } } void t_rs_generator::render_sync_handler_failed(t_function* tfunc) { string err_var("e"); - f_gen_ << indent() << "match " << err_var << " {" << endl; + f_gen_ << indent() << "match " << err_var << " {" << '\n'; indent_up(); // if there are any user-defined exceptions for this service call handle them first if (tfunc->get_xceptions() != nullptr && tfunc->get_xceptions()->get_sorted_members().size() > 0) { string user_err_var("usr_err"); - f_gen_ << indent() << "thrift::Error::User(" << user_err_var << ") => {" << endl; + f_gen_ << indent() << "thrift::Error::User(" << user_err_var << ") => {" << '\n'; indent_up(); render_sync_handler_failed_user_exception_branch(tfunc); indent_down(); - f_gen_ << indent() << "}," << endl; + f_gen_ << indent() << "}," << '\n'; } // application error string app_err_var("app_err"); - f_gen_ << indent() << "thrift::Error::Application(" << app_err_var << ") => {" << endl; + f_gen_ << indent() << "thrift::Error::Application(" << app_err_var << ") => {" << '\n'; indent_up(); render_sync_handler_failed_application_exception_branch(tfunc, app_err_var); indent_down(); - f_gen_ << indent() << "}," << endl; + f_gen_ << indent() << "}," << '\n'; // default case - f_gen_ << indent() << "_ => {" << endl; + f_gen_ << indent() << "_ => {" << '\n'; indent_up(); render_sync_handler_failed_default_exception_branch(tfunc); indent_down(); - f_gen_ << indent() << "}," << endl; + f_gen_ << indent() << "}," << '\n'; indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; } void t_rs_generator::render_sync_handler_failed_user_exception_branch(t_function* tfunc) { @@ -2670,11 +2669,11 @@ void t_rs_generator::render_sync_handler_failed_user_exception_branch(t_function string if_statement(branches_rendered == 0 ? "if usr_err" : "} else if usr_err"); string exception_type(to_rust_type(xception_field->get_type())); f_gen_ << indent() << if_statement << ".downcast_ref::<" << exception_type << ">().is_some() {" - << endl; + << '\n'; indent_up(); f_gen_ << indent() << "let err = usr_err.downcast::<" << exception_type - << ">().expect(\"downcast already checked\");" << endl; + << ">().expect(\"downcast already checked\");" << '\n'; // render the members of the return struct ostringstream members; @@ -2701,17 +2700,17 @@ void t_rs_generator::render_sync_handler_failed_user_exception_branch(t_function // now write out the return struct f_gen_ << indent() << "let ret_err = " << service_call_result_struct_name(tfunc) << "{ " - << member_string << "};" << endl; + << member_string << "};" << '\n'; f_gen_ << indent() << "let message_ident = " << "TMessageIdentifier::new(" << "\"" << tfunc->get_name() << "\", " // note: use *original* name << "TMessageType::Reply, " - << "incoming_sequence_number);" << endl; - f_gen_ << indent() << "o_prot.write_message_begin(&message_ident)?;" << endl; - f_gen_ << indent() << "ret_err.write_to_out_protocol(o_prot)?;" << endl; - f_gen_ << indent() << "o_prot.write_message_end()?;" << endl; - f_gen_ << indent() << "o_prot.flush()" << endl; + << "incoming_sequence_number);" << '\n'; + f_gen_ << indent() << "o_prot.write_message_begin(&message_ident)?;" << '\n'; + f_gen_ << indent() << "ret_err.write_to_out_protocol(o_prot)?;" << '\n'; + f_gen_ << indent() << "o_prot.write_message_end()?;" << '\n'; + f_gen_ << indent() << "o_prot.flush()" << '\n'; indent_down(); @@ -2719,41 +2718,41 @@ void t_rs_generator::render_sync_handler_failed_user_exception_branch(t_function } // the catch all, if somehow it was a user exception that we don't support - f_gen_ << indent() << "} else {" << endl; + f_gen_ << indent() << "} else {" << '\n'; indent_up(); // FIXME: same as default block below - f_gen_ << indent() << "let ret_err = {" << endl; + f_gen_ << indent() << "let ret_err = {" << '\n'; indent_up(); render_thrift_error_struct("ApplicationError", "ApplicationErrorKind::Unknown", "usr_err.to_string()"); indent_down(); - f_gen_ << indent() << "};" << endl; + f_gen_ << indent() << "};" << '\n'; render_sync_handler_send_exception_response(tfunc, "ret_err"); indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}" << '\n'; } void t_rs_generator::render_sync_handler_failed_application_exception_branch( t_function* tfunc, const string& app_err_var) { if (tfunc->is_oneway()) { - f_gen_ << indent() << "Err(thrift::Error::Application(" << app_err_var << "))" << endl; + f_gen_ << indent() << "Err(thrift::Error::Application(" << app_err_var << "))" << '\n'; } else { render_sync_handler_send_exception_response(tfunc, app_err_var); } } void t_rs_generator::render_sync_handler_failed_default_exception_branch(t_function* tfunc) { - f_gen_ << indent() << "let ret_err = {" << endl; + f_gen_ << indent() << "let ret_err = {" << '\n'; indent_up(); render_thrift_error_struct("ApplicationError", "ApplicationErrorKind::Unknown", "e.to_string()"); indent_down(); - f_gen_ << indent() << "};" << endl; + f_gen_ << indent() << "};" << '\n'; if (tfunc->is_oneway()) { - f_gen_ << indent() << "Err(thrift::Error::Application(ret_err))" << endl; + f_gen_ << indent() << "Err(thrift::Error::Application(ret_err))" << '\n'; } else { render_sync_handler_send_exception_response(tfunc, "ret_err"); } @@ -2764,12 +2763,12 @@ void t_rs_generator::render_sync_handler_send_exception_response(t_function* tfu f_gen_ << indent() << "let message_ident = TMessageIdentifier::new(" << "\"" << tfunc->get_name() << "\", " // note: use *original* name << "TMessageType::Exception, " - << "incoming_sequence_number);" << endl; - f_gen_ << indent() << "o_prot.write_message_begin(&message_ident)?;" << endl; + << "incoming_sequence_number);" << '\n'; + f_gen_ << indent() << "o_prot.write_message_begin(&message_ident)?;" << '\n'; f_gen_ << indent() << "thrift::Error::write_application_error_to_out_protocol(&" << err_var - << ", o_prot)?;" << endl; - f_gen_ << indent() << "o_prot.write_message_end()?;" << endl; - f_gen_ << indent() << "o_prot.flush()" << endl; + << ", o_prot)?;" << '\n'; + f_gen_ << indent() << "o_prot.write_message_end()?;" << '\n'; + f_gen_ << indent() << "o_prot.flush()" << '\n'; } string t_rs_generator::handler_successful_return_struct(t_function* tfunc) { @@ -2811,10 +2810,10 @@ string t_rs_generator::handler_successful_return_struct(t_function* tfunc) { //----------------------------------------------------------------------------- void t_rs_generator::render_type_comment(const string& type_name) { - f_gen_ << "//" << endl; - f_gen_ << "// " << type_name << endl; - f_gen_ << "//" << endl; - f_gen_ << endl; + f_gen_ << "//" << '\n'; + f_gen_ << "// " << type_name << '\n'; + f_gen_ << "//" << '\n'; + f_gen_ << '\n'; } // NOTE: do *not* put in an extra newline after doc is generated. @@ -2831,26 +2830,26 @@ void t_rs_generator::render_thrift_error(const string& error_kind, const string& error_struct, const string& sub_error_kind, const string& error_message) { - f_gen_ << indent() << "Err(" << endl; + f_gen_ << indent() << "Err(" << '\n'; indent_up(); - f_gen_ << indent() << "thrift::Error::" << error_kind << "(" << endl; + f_gen_ << indent() << "thrift::Error::" << error_kind << "(" << '\n'; indent_up(); render_thrift_error_struct(error_struct, sub_error_kind, error_message); indent_down(); - f_gen_ << indent() << ")" << endl; + f_gen_ << indent() << ")" << '\n'; indent_down(); - f_gen_ << indent() << ")" << endl; + f_gen_ << indent() << ")" << '\n'; } void t_rs_generator::render_thrift_error_struct(const string& error_struct, const string& sub_error_kind, const string& error_message) { - f_gen_ << indent() << error_struct << "::new(" << endl; + f_gen_ << indent() << error_struct << "::new(" << '\n'; indent_up(); - f_gen_ << indent() << sub_error_kind << "," << endl; - f_gen_ << indent() << error_message << endl; + f_gen_ << indent() << sub_error_kind << "," << '\n'; + f_gen_ << indent() << error_message << '\n'; indent_down(); - f_gen_ << indent() << ")" << endl; + f_gen_ << indent() << ")" << '\n'; } bool t_rs_generator::is_double(t_type* ttype) { diff --git a/compiler/cpp/src/thrift/generate/t_st_generator.cc b/compiler/cpp/src/thrift/generate/t_st_generator.cc index b1411867124..c1ad35577e8 100644 --- a/compiler/cpp/src/thrift/generate/t_st_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_st_generator.cc @@ -43,8 +43,6 @@ using std::string; using std::stringstream; using std::vector; -static const string endl = "\n"; // avoid ostream << std::endl flushes - /** * Smalltalk code generator. * @@ -177,7 +175,7 @@ void t_st_generator::init_generator() { f_.open(f_name.c_str()); // Print header - f_ << st_autogen_comment() << endl; + f_ << st_autogen_comment() << '\n'; st_class_def(f_, program_name_); generate_class_side_definition(); @@ -219,10 +217,10 @@ string t_st_generator::st_autogen_comment() { void t_st_generator::generate_force_consts() { f_ << prefix(class_name()) << " enums keysAndValuesDo: [:k :v | " << prefix(class_name()) - << " enums at: k put: v value].!" << endl; + << " enums at: k put: v value].!" << '\n'; f_ << prefix(class_name()) << " constants keysAndValuesDo: [:k :v | " << prefix(class_name()) - << " constants at: k put: v value].!" << endl; + << " constants at: k put: v value].!" << '\n'; } void t_st_generator::close_generator() { @@ -252,11 +250,11 @@ void t_st_generator::generate_typedef(t_typedef* ttypedef) { } void t_st_generator::st_class_def(std::ostream& out, string name) { - out << "Object subclass: #" << prefix(name) << endl; + out << "Object subclass: #" << prefix(name) << '\n'; indent_up(); - out << indent() << "instanceVariableNames: ''" << endl << indent() << "classVariableNames: ''" - << endl << indent() << "poolDictionaries: ''" << endl << indent() << "category: '" - << generated_category() << "'!" << endl << endl; + out << indent() << "instanceVariableNames: ''" << '\n' << indent() << "classVariableNames: ''" + << '\n' << indent() << "poolDictionaries: ''" << '\n' << indent() << "category: '" + << generated_category() << "'!" << '\n' << '\n'; } void t_st_generator::st_method(std::ostream& out, string cls, string name) { @@ -281,14 +279,14 @@ void t_st_generator::st_method(std::ostream& out, string cls, string name, strin strftime(timestr, 50, "%m/%d/%Y %H:%M", tinfo); out << "!" << prefix(cls) << " methodsFor: '" + category + "' stamp: 'thrift " << timestr - << "'!\n" << name << endl; + << "'!\n" << name << '\n'; indent_up(); out << indent(); } void t_st_generator::st_close_method(std::ostream& out) { - out << "! !" << endl << endl; + out << "! !" << '\n' << '\n'; indent_down(); } @@ -316,16 +314,16 @@ void t_st_generator::st_accessors(std::ostream& out, } void t_st_generator::generate_class_side_definition() { - f_ << prefix(class_name()) << " class" << endl << "\tinstanceVariableNames: 'constants enums'!" - << endl << endl; + f_ << prefix(class_name()) << " class" << '\n' << "\tinstanceVariableNames: 'constants enums'!" + << '\n' << '\n'; st_accessors(f_, class_name() + " class", "enums"); st_accessors(f_, class_name() + " class", "constants"); - f_ << prefix(class_name()) << " enums: Dictionary new!" << endl; - f_ << prefix(class_name()) << " constants: Dictionary new!" << endl; + f_ << prefix(class_name()) << " enums: Dictionary new!" << '\n'; + f_ << prefix(class_name()) << " constants: Dictionary new!" << '\n'; - f_ << endl; + f_ << '\n'; } /** @@ -338,16 +336,16 @@ void t_st_generator::generate_enum(t_enum* tenum) { string cls_name = program_name_ + capitalize(tenum->get_name()); f_ << prefix(class_name()) << " enums at: '" << tenum->get_name() << "' put: [" - << "(Dictionary new " << endl; + << "(Dictionary new " << '\n'; vector constants = tenum->get_constants(); vector::iterator c_iter; for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) { int value = (*c_iter)->get_value(); - f_ << "\tat: '" << (*c_iter)->get_name() << "' put: " << value << ";" << endl; + f_ << "\tat: '" << (*c_iter)->get_name() << "' put: " << value << ";" << '\n'; } - f_ << "\tyourself)]!" << endl << endl; + f_ << "\tyourself)]!" << '\n' << '\n'; } /** @@ -359,7 +357,7 @@ void t_st_generator::generate_const(t_const* tconst) { t_const_value* value = tconst->get_value(); f_ << prefix(class_name()) << " constants at: '" << name << "' put: [" - << render_const_value(type, value) << "]!" << endl << endl; + << render_const_value(type, value) << "]!" << '\n' << '\n'; } /** @@ -398,7 +396,7 @@ string t_st_generator::render_const_value(t_type* type, t_const_value* value) { } else if (type->is_enum()) { indent(out) << value->get_integer(); } else if (type->is_struct() || type->is_xception()) { - out << "(" << capitalize(type->get_name()) << " new " << endl; + out << "(" << capitalize(type->get_name()) << " new " << '\n'; indent_up(); const vector& fields = ((t_struct*)type)->get_members(); @@ -418,7 +416,7 @@ string t_st_generator::render_const_value(t_type* type, t_const_value* value) { } out << indent() << v_iter->first->get_string() << ": " - << render_const_value(field_type, v_iter->second) << ";" << endl; + << render_const_value(field_type, v_iter->second) << ";" << '\n'; } out << indent() << "yourself)"; @@ -426,7 +424,7 @@ string t_st_generator::render_const_value(t_type* type, t_const_value* value) { } else if (type->is_map()) { t_type* ktype = ((t_map*)type)->get_key_type(); t_type* vtype = ((t_map*)type)->get_val_type(); - out << "(Dictionary new" << endl; + out << "(Dictionary new" << '\n'; indent_up(); indent_up(); const map& val = value->get_map(); @@ -436,7 +434,7 @@ string t_st_generator::render_const_value(t_type* type, t_const_value* value) { out << "at: " << render_const_value(ktype, v_iter->first); out << " put: "; out << render_const_value(vtype, v_iter->second); - out << ";" << endl; + out << ";" << '\n'; } out << indent() << indent() << "yourself)"; indent_down(); @@ -449,9 +447,9 @@ string t_st_generator::render_const_value(t_type* type, t_const_value* value) { etype = ((t_set*)type)->get_elem_type(); } if (type->is_set()) { - out << "(Set new" << endl; + out << "(Set new" << '\n'; } else { - out << "(OrderedCollection new" << endl; + out << "(OrderedCollection new" << '\n'; } indent_up(); indent_up(); @@ -460,7 +458,7 @@ string t_st_generator::render_const_value(t_type* type, t_const_value* value) { for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { out << indent() << indent(); out << "add: " << render_const_value(etype, *v_iter); - out << ";" << endl; + out << ";" << '\n'; } out << indent() << indent() << "yourself)"; indent_down(); @@ -502,7 +500,7 @@ void t_st_generator::generate_st_struct(std::ostream& out, else out << "Object"; - out << " subclass: #" << prefix(type_name(tstruct)) << endl << "\tinstanceVariableNames: '"; + out << " subclass: #" << prefix(type_name(tstruct)) << '\n' << "\tinstanceVariableNames: '"; if (members.size() > 0) { for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { @@ -556,7 +554,7 @@ void t_st_generator::generate_accessors(std::ostream& out, t_struct* tstruct) { camelcase((*m_iter)->get_name()), a_type((*m_iter)->get_type())); } - out << endl; + out << '\n'; } } @@ -583,17 +581,17 @@ string t_st_generator::map_writer(t_map* tmap, string fname) { out << "[oprot writeMapBegin: (TMap new keyType: " << type_to_enum(tmap->get_key_type()) << "; valueType: " << type_to_enum(tmap->get_val_type()) << "; size: " << fname << " size)." - << endl; + << '\n'; indent_up(); - out << indent() << fname << " keysAndValuesDo: [:" << key << " :" << val << " |" << endl; + out << indent() << fname << " keysAndValuesDo: [:" << key << " :" << val << " |" << '\n'; indent_up(); - out << indent() << write_val(tmap->get_key_type(), key) << "." << endl << indent() + out << indent() << write_val(tmap->get_key_type(), key) << "." << '\n' << indent() << write_val(tmap->get_val_type(), val); indent_down(); - out << "]." << endl << indent() << "oprot writeMapEnd] value"; + out << "]." << '\n' << indent() << "oprot writeMapEnd] value"; indent_down(); return out.str(); @@ -604,18 +602,18 @@ string t_st_generator::map_reader(t_map* tmap) { string desc = temp_name(); string val = temp_name(); - out << "[|" << desc << " " << val << "| " << endl; + out << "[|" << desc << " " << val << "| " << '\n'; indent_up(); - out << indent() << desc << " := iprot readMapBegin." << endl << indent() << val - << " := Dictionary new." << endl << indent() << desc << " size timesRepeat: [" << endl; + out << indent() << desc << " := iprot readMapBegin." << '\n' << indent() << val + << " := Dictionary new." << '\n' << indent() << desc << " size timesRepeat: [" << '\n'; indent_up(); out << indent() << val << " at: " << read_val(tmap->get_key_type()) << " put: " << read_val(tmap->get_val_type()); indent_down(); - out << "]." << endl << indent() << "iprot readMapEnd." << endl << indent() << val << "] value"; + out << "]." << '\n' << indent() << "iprot readMapEnd." << '\n' << indent() << val << "] value"; indent_down(); return out.str(); @@ -626,16 +624,16 @@ string t_st_generator::list_writer(t_list* tlist, string fname) { string val = temp_name(); out << "[oprot writeListBegin: (TList new elemType: " << type_to_enum(tlist->get_elem_type()) - << "; size: " << fname << " size)." << endl; + << "; size: " << fname << " size)." << '\n'; indent_up(); - out << indent() << fname << " do: [:" << val << "|" << endl; + out << indent() << fname << " do: [:" << val << "|" << '\n'; indent_up(); - out << indent() << write_val(tlist->get_elem_type(), val) << endl; + out << indent() << write_val(tlist->get_elem_type(), val) << '\n'; indent_down(); - out << "]." << endl << indent() << "oprot writeListEnd] value"; + out << "]." << '\n' << indent() << "oprot writeListEnd] value"; indent_down(); return out.str(); @@ -646,17 +644,17 @@ string t_st_generator::list_reader(t_list* tlist) { string desc = temp_name(); string val = temp_name(); - out << "[|" << desc << " " << val << "| " << desc << " := iprot readListBegin." << endl; + out << "[|" << desc << " " << val << "| " << desc << " := iprot readListBegin." << '\n'; indent_up(); - out << indent() << val << " := OrderedCollection new." << endl << indent() << desc - << " size timesRepeat: [" << endl; + out << indent() << val << " := OrderedCollection new." << '\n' << indent() << desc + << " size timesRepeat: [" << '\n'; indent_up(); out << indent() << val << " add: " << read_val(tlist->get_elem_type()); indent_down(); - out << "]." << endl << indent() << "iprot readListEnd." << endl << indent() << val << "] value"; + out << "]." << '\n' << indent() << "iprot readListEnd." << '\n' << indent() << val << "] value"; indent_down(); return out.str(); @@ -667,16 +665,16 @@ string t_st_generator::set_writer(t_set* tset, string fname) { string val = temp_name(); out << "[oprot writeSetBegin: (TSet new elemType: " << type_to_enum(tset->get_elem_type()) - << "; size: " << fname << " size)." << endl; + << "; size: " << fname << " size)." << '\n'; indent_up(); - out << indent() << fname << " do: [:" << val << "|" << endl; + out << indent() << fname << " do: [:" << val << "|" << '\n'; indent_up(); - out << indent() << write_val(tset->get_elem_type(), val) << endl; + out << indent() << write_val(tset->get_elem_type(), val) << '\n'; indent_down(); - out << "]." << endl << indent() << "oprot writeSetEnd] value"; + out << "]." << '\n' << indent() << "oprot writeSetEnd] value"; indent_down(); return out.str(); @@ -687,17 +685,17 @@ string t_st_generator::set_reader(t_set* tset) { string desc = temp_name(); string val = temp_name(); - out << "[|" << desc << " " << val << "| " << desc << " := iprot readSetBegin." << endl; + out << "[|" << desc << " " << val << "| " << desc << " := iprot readSetBegin." << '\n'; indent_up(); - out << indent() << val << " := Set new." << endl << indent() << desc << " size timesRepeat: [" - << endl; + out << indent() << val << " := Set new." << '\n' << indent() << desc << " size timesRepeat: [" + << '\n'; indent_up(); out << indent() << val << " add: " << read_val(tset->get_elem_type()); indent_down(); - out << "]." << endl << indent() << "iprot readSetEnd." << endl << indent() << val << "] value"; + out << "]." << '\n' << indent() << "iprot readSetEnd." << '\n' << indent() << val << "] value"; indent_down(); return out.str(); @@ -709,7 +707,7 @@ string t_st_generator::struct_writer(t_struct* tstruct, string sname) { vector::const_iterator fld_iter; out << "[oprot writeStructBegin: " - << "(TStruct new name: '" + tstruct->get_name() + "')." << endl; + << "(TStruct new name: '" + tstruct->get_name() + "')." << '\n'; indent_up(); for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) { @@ -718,15 +716,15 @@ string t_st_generator::struct_writer(t_struct* tstruct, string sname) { string accessor = sname + " " + camelcase(fname); if (optional) { - out << indent() << accessor << " ifNotNil: [" << endl; + out << indent() << accessor << " ifNotNil: [" << '\n'; indent_up(); } out << indent() << "oprot writeFieldBegin: (TField new name: '" << fname << "'; type: " << type_to_enum((*fld_iter)->get_type()) - << "; id: " << (*fld_iter)->get_key() << ")." << endl; + << "; id: " << (*fld_iter)->get_key() << ")." << '\n'; - out << indent() << write_val((*fld_iter)->get_type(), accessor) << "." << endl << indent() + out << indent() << write_val((*fld_iter)->get_type(), accessor) << "." << '\n' << indent() << "oprot writeFieldEnd"; if (optional) { @@ -734,7 +732,7 @@ string t_st_generator::struct_writer(t_struct* tstruct, string sname) { indent_down(); } - out << "." << endl; + out << "." << '\n'; } out << indent() << "oprot writeFieldStop; writeStructEnd] value"; @@ -755,33 +753,33 @@ string t_st_generator::struct_reader(t_struct* tstruct, string clsName = "") { clsName = tstruct->get_name(); } - out << "[|" << desc << " " << val << "|" << endl; + out << "[|" << desc << " " << val << "|" << '\n'; indent_up(); // This is nasty, but without it we'll break things by prefixing TResult. string name = ((capitalize(clsName) == "TResult") ? capitalize(clsName) : prefix(clsName)); - out << indent() << val << " := " << name << " new." << endl; + out << indent() << val << " := " << name << " new." << '\n'; - out << indent() << "iprot readStructBegin." << endl << indent() << "[" << desc - << " := iprot readFieldBegin." << endl << indent() << desc - << " type = TType stop] whileFalse: [|" << found << "|" << endl; + out << indent() << "iprot readStructBegin." << '\n' << indent() << "[" << desc + << " := iprot readFieldBegin." << '\n' << indent() << desc + << " type = TType stop] whileFalse: [|" << found << "|" << '\n'; indent_up(); for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) { - out << indent() << desc << " id = " << (*fld_iter)->get_key() << " ifTrue: [" << endl; + out << indent() << desc << " id = " << (*fld_iter)->get_key() << " ifTrue: [" << '\n'; indent_up(); - out << indent() << found << " := true." << endl << indent() << val << " " + out << indent() << found << " := true." << '\n' << indent() << val << " " << camelcase((*fld_iter)->get_name()) << ": " << read_val((*fld_iter)->get_type()); indent_down(); - out << "]." << endl; + out << "]." << '\n'; } - out << indent() << found << " ifNil: [iprot skip: " << desc << " type]]." << endl; + out << indent() << found << " ifNil: [iprot skip: " << desc << " type]]." << '\n'; indent_down(); - out << indent() << "oprot readStructEnd." << endl << indent() << val << "] value"; + out << indent() << "oprot readStructEnd." << '\n' << indent() << val << "] value"; indent_down(); return out.str(); @@ -847,32 +845,32 @@ void t_st_generator::generate_send_method(t_function* function) { vector::const_iterator fld_iter; st_method(f_, client_class_name(), "send" + capitalize(signature)); - f_ << "oprot writeMessageBegin:" << endl; + f_ << "oprot writeMessageBegin:" << '\n'; indent_up(); - f_ << indent() << "(TCallMessage new" << endl; + f_ << indent() << "(TCallMessage new" << '\n'; indent_up(); - f_ << indent() << "name: '" << funname << "'; " << endl << indent() << "seqid: self nextSeqid)." - << endl; + f_ << indent() << "name: '" << funname << "'; " << '\n' << indent() << "seqid: self nextSeqid)." + << '\n'; indent_down(); indent_down(); f_ << indent() << "oprot writeStructBegin: " - << "(TStruct new name: '" + capitalize(camelcase(funname)) + "_args')." << endl; + << "(TStruct new name: '" + capitalize(camelcase(funname)) + "_args')." << '\n'; for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) { string fname = camelcase((*fld_iter)->get_name()); f_ << indent() << "oprot writeFieldBegin: (TField new name: '" << fname << "'; type: " << type_to_enum((*fld_iter)->get_type()) << "; id: " << (*fld_iter)->get_key() - << ")." << endl; + << ")." << '\n'; - f_ << indent() << write_val((*fld_iter)->get_type(), fname) << "." << endl << indent() - << "oprot writeFieldEnd." << endl; + f_ << indent() << write_val((*fld_iter)->get_type(), fname) << "." << '\n' << indent() + << "oprot writeFieldEnd." << '\n'; } - f_ << indent() << "oprot writeFieldStop; writeStructEnd; writeMessageEnd." << endl; + f_ << indent() << "oprot writeFieldStop; writeStructEnd; writeMessageEnd." << '\n'; f_ << indent() << "oprot transport flush"; st_close_method(f_); @@ -897,11 +895,11 @@ void t_st_generator::generate_recv_method(t_function* function) { } st_method(f_, client_class_name(), "recv" + capitalize(funname)); - f_ << "| f msg res | " << endl << indent() << "msg := oprot readMessageBegin." << endl << indent() - << "self validateRemoteMessage: msg." << endl << indent() - << "res := " << struct_reader(&result) << "." << endl << indent() << "oprot readMessageEnd." - << endl << indent() << "oprot transport flush." << endl << indent() - << "res exception ifNotNil: [res exception signal]." << endl << indent() << "^ res"; + f_ << "| f msg res | " << '\n' << indent() << "msg := oprot readMessageBegin." << '\n' << indent() + << "self validateRemoteMessage: msg." << '\n' << indent() + << "res := " << struct_reader(&result) << "." << '\n' << indent() << "oprot readMessageEnd." + << '\n' << indent() << "oprot transport flush." << '\n' << indent() + << "res exception ifNotNil: [res exception signal]." << '\n' << indent() << "^ res"; st_close_method(f_); } @@ -940,7 +938,7 @@ void t_st_generator::generate_service_client(t_service* tservice) { extends_client = extends + "Client"; } - f_ << extends_client << " subclass: #" << prefix(client_class_name()) << endl + f_ << extends_client << " subclass: #" << prefix(client_class_name()) << '\n' << "\tinstanceVariableNames: ''\n" << "\tclassVariableNames: ''\n" << "\tpoolDictionaries: ''\n" @@ -951,11 +949,11 @@ void t_st_generator::generate_service_client(t_service* tservice) { string signature = function_signature(*f_iter); st_method(f_, client_class_name(), signature); - f_ << function_types_comment(*f_iter) << endl << indent() << "self send" - << capitalize(signature) << "." << endl; + f_ << function_types_comment(*f_iter) << '\n' << indent() << "self send" + << capitalize(signature) << "." << '\n'; if (!(*f_iter)->is_oneway()) { - f_ << indent() << "^ self recv" << capitalize(funname) << " success " << endl; + f_ << indent() << "^ self recv" << capitalize(funname) << " success " << '\n'; } st_close_method(f_); diff --git a/compiler/cpp/src/thrift/generate/t_swift_generator.cc b/compiler/cpp/src/thrift/generate/t_swift_generator.cc index fab14135ae7..98b19ecada0 100644 --- a/compiler/cpp/src/thrift/generate/t_swift_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_swift_generator.cc @@ -37,8 +37,6 @@ using std::string; using std::stringstream; using std::vector; -static const string endl = "\n"; // avoid ostream << std::endl flushes - /** * Swift 3 code generator. * @@ -51,7 +49,7 @@ class t_swift_generator : public t_oop_generator { const string& option_string) : t_oop_generator(program) { update_keywords_for_validation(); - + (void)option_string; map::const_iterator iter; @@ -226,14 +224,14 @@ class t_swift_generator : public t_oop_generator { private: void block_open(ostream& out) { - out << " {" << endl; + out << " {" << '\n'; indent_up(); } void block_close(ostream& out, bool end_line=true) { indent_down(); indent(out) << "}"; - if (end_line) out << endl; + if (end_line) out << '\n'; } bool field_is_optional(t_field* tfield) { @@ -320,18 +318,18 @@ void t_swift_generator::init_generator() { string f_decl_fullname = module_path + "/" + f_decl_name; f_decl_.open(f_decl_fullname.c_str()); - f_decl_ << autogen_comment() << endl; + f_decl_ << autogen_comment() << '\n'; - f_decl_ << swift_imports() << swift_thrift_imports() << endl; + f_decl_ << swift_imports() << swift_thrift_imports() << '\n'; // ...and a .swift implementation extensions file string f_impl_name = name + "+Exts.swift"; string f_impl_fullname = module_path + "/" + f_impl_name; f_impl_.open(f_impl_fullname.c_str()); - f_impl_ << autogen_comment() << endl; + f_impl_ << autogen_comment() << '\n'; - f_impl_ << swift_imports() << swift_thrift_imports() << endl; + f_impl_ << swift_imports() << swift_thrift_imports() << '\n'; } @@ -349,16 +347,16 @@ string t_swift_generator::swift_imports() { vector::const_iterator i_iter; for (i_iter=includes_list.begin(); i_iter!=includes_list.end(); ++i_iter) { - includes << "import " << *i_iter << endl; + includes << "import " << *i_iter << '\n'; } if (namespaced_) { const vector& program_includes = program_->get_includes(); for (auto program_include : program_includes) { - includes << ("import " + get_real_swift_module(program_include)) << endl; + includes << ("import " + get_real_swift_module(program_include)) << '\n'; } } - includes << endl; + includes << '\n'; return includes.str(); } @@ -381,10 +379,10 @@ string t_swift_generator::swift_thrift_imports() { vector::const_iterator i_iter; for (i_iter=includes_list.begin(); i_iter!=includes_list.end(); ++i_iter) { - includes << "import " << *i_iter << endl; + includes << "import " << *i_iter << '\n'; } - includes << endl; + includes << '\n'; return includes.str(); } @@ -395,7 +393,7 @@ string t_swift_generator::swift_thrift_imports() { void t_swift_generator::close_generator() { // stick our constants declarations at the end of the header file // since they refer to things we are defining. - f_decl_ << constants_declarations_ << endl; + f_decl_ << constants_declarations_ << '\n'; } /** @@ -405,8 +403,8 @@ void t_swift_generator::close_generator() { */ void t_swift_generator::generate_typedef(t_typedef* ttypedef) { f_decl_ << indent() << "public typealias " << ttypedef->get_symbolic() - << " = " << type_name(ttypedef->get_type()) << endl; - f_decl_ << endl; + << " = " << type_name(ttypedef->get_type()) << '\n'; + f_decl_ << '\n'; } @@ -430,80 +428,80 @@ void t_swift_generator::generate_enum(t_enum* tenum) { vector::iterator c_iter; for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) { - f_decl_ << indent() << "case " << enum_case_name((*c_iter), true) << endl; + f_decl_ << indent() << "case " << enum_case_name((*c_iter), true) << '\n'; } // unknown associated value case for safety and similar behavior to other languages if (safe_enums_) { - f_decl_ << indent() << "case unknown(Int32)" << endl; + f_decl_ << indent() << "case unknown(Int32)" << '\n'; } - f_decl_ << endl; + f_decl_ << '\n'; // TSerializable read(from:) f_decl_ << indent() << "public static func read(from proto: TProtocol) throws -> " << tenum->get_name(); block_open(f_decl_); - f_decl_ << indent() << "let raw: Int32 = try proto.read()" << endl; - f_decl_ << indent() << "let new = " << tenum->get_name() << "(rawValue: raw)" << endl; + f_decl_ << indent() << "let raw: Int32 = try proto.read()" << '\n'; + f_decl_ << indent() << "let new = " << tenum->get_name() << "(rawValue: raw)" << '\n'; - f_decl_ << indent() << "if let unwrapped = new {" << endl; + f_decl_ << indent() << "if let unwrapped = new {" << '\n'; indent_up(); - f_decl_ << indent() << "return unwrapped" << endl; + f_decl_ << indent() << "return unwrapped" << '\n'; indent_down(); - f_decl_ << indent() << "} else {" << endl; + f_decl_ << indent() << "} else {" << '\n'; indent_up(); - f_decl_ << indent() << "throw TProtocolError(error: .invalidData," << endl; + f_decl_ << indent() << "throw TProtocolError(error: .invalidData," << '\n'; f_decl_ << indent() << " message: \"Invalid enum value (\\(raw)) for \\(" - << tenum->get_name() << ".self)\")" << endl; + << tenum->get_name() << ".self)\")" << '\n'; indent_down(); - f_decl_ << indent() << "}" << endl; + f_decl_ << indent() << "}" << '\n'; block_close(f_decl_); // empty init for TSerializable - f_decl_ << endl; + f_decl_ << '\n'; f_decl_ << indent() << "public init()"; block_open(f_decl_); - f_decl_ << indent() << "self = ." << enum_case_name(constants.front(), false) << endl; + f_decl_ << indent() << "self = ." << enum_case_name(constants.front(), false) << '\n'; block_close(f_decl_); - f_decl_ << endl; + f_decl_ << '\n'; // rawValue getter f_decl_ << indent() << "public var rawValue: Int32"; block_open(f_decl_); - f_decl_ << indent() << "switch self {" << endl; + f_decl_ << indent() << "switch self {" << '\n'; for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) { f_decl_ << indent() << "case ." << enum_case_name((*c_iter), true) - << ": return " << (*c_iter)->get_value() << endl; + << ": return " << (*c_iter)->get_value() << '\n'; } if (safe_enums_) { - f_decl_ << indent() << "case .unknown(let value): return value" << endl; + f_decl_ << indent() << "case .unknown(let value): return value" << '\n'; } - f_decl_ << indent() << "}" << endl; + f_decl_ << indent() << "}" << '\n'; block_close(f_decl_); - f_decl_ << endl; + f_decl_ << '\n'; // convenience rawValue initalizer f_decl_ << indent() << "public init?(rawValue: Int32)"; block_open(f_decl_); - f_decl_ << indent() << "switch rawValue {" << endl;; + f_decl_ << indent() << "switch rawValue {" << '\n';; for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) { f_decl_ << indent() << "case " << (*c_iter)->get_value() - << ": self = ." << enum_case_name((*c_iter), true) << endl; + << ": self = ." << enum_case_name((*c_iter), true) << '\n'; } if (!safe_enums_) { - f_decl_ << indent() << "default: return nil" << endl; + f_decl_ << indent() << "default: return nil" << '\n'; } else { - f_decl_ << indent() << "default: self = .unknown(rawValue)" << endl; + f_decl_ << indent() << "default: self = .unknown(rawValue)" << '\n'; } - f_decl_ << indent() << "}" << endl; + f_decl_ << indent() << "}" << '\n'; block_close(f_decl_); block_close(f_decl_); - f_decl_ << endl; + f_decl_ << '\n'; } /** @@ -521,36 +519,36 @@ void t_swift_generator::generate_old_enum(t_enum* tenum) { for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) { f_decl_ << indent() << "case " << (*c_iter)->get_name() - << " = " << (*c_iter)->get_value() << endl; + << " = " << (*c_iter)->get_value() << '\n'; } - f_decl_ << endl; - f_decl_ << indent() << "public init() { self.init(rawValue: " << constants.front()->get_value() << ")! }" << endl; + f_decl_ << '\n'; + f_decl_ << indent() << "public init() { self.init(rawValue: " << constants.front()->get_value() << ")! }" << '\n'; block_close(f_decl_); - f_decl_ << endl; + f_decl_ << '\n'; f_impl_ << indent() << "extension " << tenum->get_name() << " : TEnum"; block_open(f_impl_); - f_impl_ << endl; + f_impl_ << '\n'; f_impl_ << indent() << "public static func readValueFromProtocol(proto: TProtocol) throws -> " << tenum->get_name(); block_open(f_impl_); - f_impl_ << indent() << "var raw = Int32()" << endl - << indent() << "try proto.readI32(&raw)" << endl - << indent() << "return " << tenum->get_name() << "(rawValue: raw)!" << endl; + f_impl_ << indent() << "var raw = Int32()" << '\n' + << indent() << "try proto.readI32(&raw)" << '\n' + << indent() << "return " << tenum->get_name() << "(rawValue: raw)!" << '\n'; block_close(f_impl_); - f_impl_ << endl; + f_impl_ << '\n'; f_impl_ << indent() << "public static func writeValue(value: " << tenum->get_name() << ", toProtocol proto: TProtocol) throws"; block_open(f_impl_); - f_impl_ << indent() << "try proto.writeI32(value.rawValue)" << endl; + f_impl_ << indent() << "try proto.writeI32(value.rawValue)" << '\n'; block_close(f_impl_); - f_impl_ << endl; + f_impl_ << '\n'; block_close(f_impl_); - f_impl_ << endl; + f_impl_ << '\n'; } string t_swift_generator::enum_case_name(t_enum_value* tenum_case, bool declaration) { @@ -593,7 +591,7 @@ void t_swift_generator::generate_consts(vector consts) { t_type* type = (*c_iter)->get_type(); const_interface << "public let " << capitalize((*c_iter)->get_name()) << " : " << type_name(type) << " = "; render_const_value(const_interface, type, (*c_iter)->get_value()); - const_interface << endl << endl; + const_interface << '\n' << '\n'; } // this gets spit into the header file in ::close_generator @@ -647,7 +645,7 @@ void t_swift_generator::generate_docstring(ostream& out, string& doc) { vector::const_iterator d_iter; for (d_iter = strings.begin(); d_iter != strings.end(); ++d_iter) { if ((*d_iter) != "") { - out << indent() << "/// " << (*d_iter) << endl; + out << indent() << "/// " << (*d_iter) << '\n'; } } } @@ -685,12 +683,12 @@ void t_swift_generator::generate_swift_struct(ostream& out, out << indent() << "public enum " << tstruct->get_name(); block_open(out); for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { - out << endl; + out << '\n'; string doc = (*m_iter)->get_doc(); generate_docstring(out, doc); out << indent() << "case " << maybe_escape_identifier((*m_iter)->get_name()) << "(val: " - << type_name((*m_iter)->get_type(), false) << ")" << endl; + << type_name((*m_iter)->get_type(), false) << ")" << '\n'; } } else { // Normal structs @@ -707,20 +705,20 @@ void t_swift_generator::generate_swift_struct(ostream& out, vector sorted = members; sort(sorted.begin(), sorted.end(), [](t_field *a, t_field *b) { return (a->get_key() < b->get_key()); } ); for (m_iter = sorted.begin(); m_iter != sorted.end(); ++m_iter) { - out << endl; + out << '\n'; // TODO: Defaults string doc = (*m_iter)->get_doc(); generate_docstring(out, doc); - out << indent() << declare_property(*m_iter, is_private) << endl; + out << indent() << declare_property(*m_iter, is_private) << '\n'; } - out << endl; - out << endl; + out << '\n'; + out << '\n'; if (!struct_has_required_fields(tstruct)) { - indent(out) << visibility << " init() { }" << endl; + indent(out) << visibility << " init() { }" << '\n'; } if (struct_has_required_fields(tstruct)) { generate_swift_struct_init(out, tstruct, false, is_private); @@ -732,7 +730,7 @@ void t_swift_generator::generate_swift_struct(ostream& out, block_close(out); - out << endl; + out << '\n'; } /** @@ -761,11 +759,11 @@ void t_swift_generator::generate_old_swift_struct(ostream& out, vector::const_iterator m_iter; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { - out << endl; - out << indent() << declare_property(*m_iter, is_private) << endl; + out << '\n'; + out << indent() << declare_property(*m_iter, is_private) << '\n'; } - out << endl; + out << '\n'; // init @@ -773,7 +771,7 @@ void t_swift_generator::generate_old_swift_struct(ostream& out, block_open(out); block_close(out); - out << endl; + out << '\n'; if (struct_has_required_fields(tstruct)) { generate_swift_struct_init(out, tstruct, false, is_private); @@ -784,7 +782,7 @@ void t_swift_generator::generate_old_swift_struct(ostream& out, block_close(out); - out << endl; + out << '\n'; } /** @@ -831,20 +829,20 @@ void t_swift_generator::generate_swift_struct_init(ostream& out, should_set = should_set || !field_is_optional((*m_iter)); if (should_set) { out << indent() << "self." << maybe_escape_identifier((*m_iter)->get_name()) << " = " - << maybe_escape_identifier((*m_iter)->get_name()) << endl; + << maybe_escape_identifier((*m_iter)->get_name()) << '\n'; } } else { /** legacy Swift2/Cocoa */ if (all || (*m_iter)->get_req() == t_field::T_REQUIRED || (*m_iter)->get_req() == t_field::T_OPT_IN_REQ_OUT) { out << indent() << "self." << maybe_escape_identifier((*m_iter)->get_name()) << " = " - << maybe_escape_identifier((*m_iter)->get_name()) << endl; + << maybe_escape_identifier((*m_iter)->get_name()) << '\n'; } } } block_close(out); - out << endl; + out << '\n'; } /** @@ -861,7 +859,7 @@ void t_swift_generator::generate_swift_struct_hashable_extension(ostream& out, string visibility = is_private ? (gen_cocoa_ ? "private" : "fileprivate") : "public"; indent(out) << "extension " << tstruct->get_name() << " : Hashable"; block_open(out); - out << endl; + out << '\n'; indent(out) << visibility << " func hash(into hasher: inout Hasher)"; block_open(out); @@ -872,21 +870,21 @@ void t_swift_generator::generate_swift_struct_hashable_extension(ostream& out, if (!tstruct->is_union()) { for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { t_field* tfield = *m_iter; - indent(out) << "hasher.combine(" << maybe_escape_identifier(tfield->get_name()) << ")" << endl; + indent(out) << "hasher.combine(" << maybe_escape_identifier(tfield->get_name()) << ")" << '\n'; } } else { - indent(out) << "switch self {" << endl; + indent(out) << "switch self {" << '\n'; for (m_iter = members.begin(); m_iter != members.end(); m_iter++) { t_field *tfield = *m_iter; - indent(out) << "case ." << tfield->get_name() << "(let val): hasher.combine(val)" << endl; + indent(out) << "case ." << tfield->get_name() << "(let val): hasher.combine(val)" << '\n'; } - indent(out) << "}" << endl << endl; + indent(out) << "}" << '\n' << '\n'; } } block_close(out); - out << endl; + out << '\n'; block_close(out); - out << endl; + out << '\n'; } /** @@ -912,7 +910,7 @@ void t_swift_generator::generate_swift_struct_equatable_extension(ostream& out, if (members.size()) { if (!tstruct->is_union()) { - out << endl; + out << '\n'; indent_up(); for (m_iter = members.begin(); m_iter != members.end();) { @@ -922,30 +920,30 @@ void t_swift_generator::generate_swift_struct_equatable_extension(ostream& out, if (++m_iter != members.end()) { out << " &&"; } - out << endl; + out << '\n'; } indent_down(); } else { block_open(out); - indent(out) << "switch (lhs, rhs) {" << endl; + indent(out) << "switch (lhs, rhs) {" << '\n'; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { t_field* tfield = *m_iter; indent(out) << "case (." << tfield->get_name() << "(let lval), ." << tfield->get_name() << "(let rval)): return lval == rval" - << endl; + << '\n'; } - indent(out) << "default: return false" << endl; - indent(out) << "}" << endl; + indent(out) << "default: return false" << '\n'; + indent(out) << "}" << '\n'; indent_down(); - indent(out) << "}()" << endl; + indent(out) << "}()" << '\n'; } } else { - out << " true" << endl; + out << " true" << '\n'; } block_close(out); - out << endl; + out << '\n'; } /** @@ -972,7 +970,7 @@ void t_swift_generator::generate_swift_struct_implementation(ostream& out, generate_swift_struct_hashable_extension(out, tstruct, is_private); generate_swift_struct_thrift_extension(out, tstruct, is_result, is_private); - out << endl << endl; + out << '\n' << '\n'; } /** @@ -993,7 +991,7 @@ void t_swift_generator::generate_swift_struct_thrift_extension(ostream& out, block_open(out); - out << endl; + out << '\n'; if (!gen_cocoa_) { /** Swift 3, no writer we just write field ID's */ string access = (is_private) ? (gen_cocoa_ ? "private" : "fileprivate") : "public"; @@ -1012,11 +1010,11 @@ void t_swift_generator::generate_swift_struct_thrift_extension(ostream& out, // pad a colon out << ":"; } - out << "]" << endl; + out << "]" << '\n'; block_close(out); - out << endl; + out << '\n'; out << indent() << access << " static var structName: String { return \"" - << tstruct->get_name() << "\" }" << endl << endl; + << tstruct->get_name() << "\" }" << '\n' << '\n'; if (tstruct->is_union()) { generate_swift_union_reader(out, tstruct); @@ -1037,24 +1035,24 @@ void t_swift_generator::generate_swift_struct_thrift_extension(ostream& out, } block_close(out); - out << endl; + out << '\n'; } void t_swift_generator::generate_swift_union_reader(ostream& out, t_struct* tstruct) { indent(out) << "public static func read(from proto: TProtocol) throws -> " << tstruct->get_name(); block_open(out); - indent(out) << "_ = try proto.readStructBegin()" << endl; + indent(out) << "_ = try proto.readStructBegin()" << '\n'; indent(out) << "var ret: " << tstruct->get_name() << "?"; - out << endl; + out << '\n'; indent(out) << "fields: while true"; block_open(out); - out << endl; - indent(out) << "let (_, fieldType, fieldID) = try proto.readFieldBegin()" << endl << endl; + out << '\n'; + indent(out) << "let (_, fieldType, fieldID) = try proto.readFieldBegin()" << '\n' << '\n'; indent(out) << "switch (fieldID, fieldType)"; block_open(out); - indent(out) << "case (_, .stop): break fields" << endl; + indent(out) << "case (_, .stop): break fields" << '\n'; const vector& fields = tstruct->get_members(); vector::const_iterator f_iter; @@ -1094,28 +1092,28 @@ void t_swift_generator::generate_swift_union_reader(ostream& out, t_struct* tstr indent(out) << padding << "ret = " << tstruct->get_name() << "." << (*f_iter)->get_name() << "(val: " << "try " << type_name((*f_iter)->get_type(), false, false) - << ".read(from: proto))" << endl; + << ".read(from: proto))" << '\n'; } - indent(out) << "case let (_, unknownType): try proto.skip(type: unknownType)" << endl; + indent(out) << "case let (_, unknownType): try proto.skip(type: unknownType)" << '\n'; block_close(out); - indent(out) << "try proto.readFieldEnd()" << endl; + indent(out) << "try proto.readFieldEnd()" << '\n'; block_close(out); - out << endl; + out << '\n'; - indent(out) << "try proto.readStructEnd()" << endl; + indent(out) << "try proto.readStructEnd()" << '\n'; indent(out) << "if let ret = ret"; block_open(out); - indent(out) << "return ret" << endl; + indent(out) << "return ret" << '\n'; block_close(out); - out << endl; + out << '\n'; indent(out) << "throw TProtocolError(error: .unknown, message: \"Missing required value for type: " << tstruct->get_name() << "\")"; block_close(out); - out << endl; + out << '\n'; } @@ -1139,7 +1137,7 @@ void t_swift_generator::generate_swift_struct_reader(ostream& out, << tstruct->get_name(); block_open(out); - indent(out) << "_ = try proto.readStructBegin()" << endl; + indent(out) << "_ = try proto.readStructBegin()" << '\n'; const vector& fields = tstruct->get_members(); vector::const_iterator f_iter; @@ -1147,20 +1145,20 @@ void t_swift_generator::generate_swift_struct_reader(ostream& out, for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { bool optional = field_is_optional(*f_iter); indent(out) << "var " << maybe_escape_identifier((*f_iter)->get_name()) << ": " - << type_name((*f_iter)->get_type(), optional, !optional) << endl; + << type_name((*f_iter)->get_type(), optional, !optional) << '\n'; } - out << endl; + out << '\n'; // Loop over reading in fields indent(out) << "fields: while true"; block_open(out); - out << endl; + out << '\n'; - indent(out) << "let (_, fieldType, fieldID) = try proto.readFieldBegin()" << endl << endl; + indent(out) << "let (_, fieldType, fieldID) = try proto.readFieldBegin()" << '\n' << '\n'; indent(out) << "switch (fieldID, fieldType)"; block_open(out); - indent(out) << "case (_, .stop): break fields" << endl; + indent(out) << "case (_, .stop): break fields" << '\n'; // Generate deserialization code for known cases @@ -1198,33 +1196,33 @@ void t_swift_generator::generate_swift_struct_reader(ostream& out, } out << padding << maybe_escape_identifier((*f_iter)->get_name()) << " = try " - << type_name((*f_iter)->get_type(), false, false) << ".read(from: proto)" << endl; + << type_name((*f_iter)->get_type(), false, false) << ".read(from: proto)" << '\n'; } - indent(out) << "case let (_, unknownType): try proto.skip(type: unknownType)" << endl; + indent(out) << "case let (_, unknownType): try proto.skip(type: unknownType)" << '\n'; block_close(out); - out << endl; + out << '\n'; // Read field end marker - indent(out) << "try proto.readFieldEnd()" << endl; + indent(out) << "try proto.readFieldEnd()" << '\n'; block_close(out); - out << endl; - indent(out) << "try proto.readStructEnd()" << endl; + out << '\n'; + indent(out) << "try proto.readStructEnd()" << '\n'; if (struct_has_required_fields(tstruct)) { // performs various checks (e.g. check that all required fields are set) - indent(out) << "// Required fields" << endl; + indent(out) << "// Required fields" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if (field_is_optional(*f_iter)) { continue; } indent(out) << "try proto.validateValue(" << maybe_escape_identifier((*f_iter)->get_name()) << ", " - << "named: \"" << (*f_iter)->get_name() << "\")" << endl; + << "named: \"" << (*f_iter)->get_name() << "\")" << '\n'; } } - out << endl; + out << '\n'; indent(out) << "return " << tstruct->get_name() << "("; for (f_iter = fields.begin(); f_iter != fields.end();) { @@ -1242,8 +1240,8 @@ void t_swift_generator::generate_swift_struct_reader(ostream& out, << tstruct->get_name(); block_open(out); - out << endl; - indent(out) << "try __proto.readStructBegin()" << endl << endl; + out << '\n'; + indent(out) << "try __proto.readStructBegin()" << '\n' << '\n'; const vector& fields = tstruct->get_members(); vector::const_iterator f_iter; @@ -1251,66 +1249,66 @@ void t_swift_generator::generate_swift_struct_reader(ostream& out, for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { bool optional = field_is_optional(*f_iter); indent(out) << "var " << maybe_escape_identifier((*f_iter)->get_name()) << " : " - << type_name((*f_iter)->get_type(), optional, !optional) << endl; + << type_name((*f_iter)->get_type(), optional, !optional) << '\n'; } - out << endl; + out << '\n'; // Loop over reading in fields indent(out) << "fields: while true"; block_open(out); - out << endl; + out << '\n'; - indent(out) << "let (_, fieldType, fieldID) = try __proto.readFieldBegin()" << endl << endl; + indent(out) << "let (_, fieldType, fieldID) = try __proto.readFieldBegin()" << '\n' << '\n'; indent(out) << "switch (fieldID, fieldType)"; block_open(out); - indent(out) << "case (_, .STOP):" << endl; + indent(out) << "case (_, .STOP):" << '\n'; indent_up(); - indent(out) << "break fields" << endl << endl; + indent(out) << "break fields" << '\n' << '\n'; indent_down(); // Generate deserialization code for known cases for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { - indent(out) << "case (" << (*f_iter)->get_key() << ", " << type_to_enum((*f_iter)->get_type()) << "):" << endl; + indent(out) << "case (" << (*f_iter)->get_key() << ", " << type_to_enum((*f_iter)->get_type()) << "):" << '\n'; indent_up(); indent(out) << maybe_escape_identifier((*f_iter)->get_name()) << " = try __proto.readValue() as " - << type_name((*f_iter)->get_type()) << endl << endl; + << type_name((*f_iter)->get_type()) << '\n' << '\n'; indent_down(); } - indent(out) << "case let (_, unknownType):" << endl; + indent(out) << "case let (_, unknownType):" << '\n'; indent_up(); - indent(out) << "try __proto.skipType(unknownType)" << endl; + indent(out) << "try __proto.skipType(unknownType)" << '\n'; indent_down(); block_close(out); - out << endl; + out << '\n'; // Read field end marker - indent(out) << "try __proto.readFieldEnd()" << endl; + indent(out) << "try __proto.readFieldEnd()" << '\n'; block_close(out); - out << endl; - indent(out) << "try __proto.readStructEnd()" << endl; - out << endl; + out << '\n'; + indent(out) << "try __proto.readStructEnd()" << '\n'; + out << '\n'; if (struct_has_required_fields(tstruct)) { // performs various checks (e.g. check that all required fields are set) - indent(out) << "// Required fields" << endl; + indent(out) << "// Required fields" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if (field_is_optional(*f_iter)) { continue; } indent(out) << "try __proto.validateValue(" << (*f_iter)->get_name() << ", " - << "named: \"" << (*f_iter)->get_name() << "\")" << endl; + << "named: \"" << (*f_iter)->get_name() << "\")" << '\n'; } } - out << endl; + out << '\n'; indent(out) << "return " << tstruct->get_name() << "("; for (f_iter = fields.begin(); f_iter != fields.end();) { @@ -1320,11 +1318,11 @@ void t_swift_generator::generate_swift_struct_reader(ostream& out, } } } - out << ")" << endl; + out << ")" << '\n'; block_close(out); - out << endl; + out << '\n'; } /** @@ -1344,14 +1342,14 @@ void t_swift_generator::generate_old_swift_struct_writer(ostream& out, indent(out) << visibility << " static func writeValue(__value: " << tstruct->get_name() << ", toProtocol __proto: TProtocol) throws"; block_open(out); - out << endl; + out << '\n'; string name = tstruct->get_name(); const vector& fields = tstruct->get_members(); vector::const_iterator f_iter; - indent(out) << "try __proto.writeStructBeginWithName(\"" << name << "\")" << endl; - out << endl; + indent(out) << "try __proto.writeStructBeginWithName(\"" << name << "\")" << '\n'; + out << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { t_field *tfield = *f_iter; @@ -1367,19 +1365,19 @@ void t_swift_generator::generate_old_swift_struct_writer(ostream& out, << (optional ? "" : "__value.") << maybe_escape_identifier(tfield->get_name()) << ", " << "name: \"" << tfield->get_name() << "\", " << "type: " << type_to_enum(tfield->get_type()) << ", " - << "id: " << tfield->get_key() << ")" << endl; + << "id: " << tfield->get_key() << ")" << '\n'; if (optional) { block_close(out); } - out << endl; + out << '\n'; } - indent(out) << "try __proto.writeFieldStop()" << endl << endl; - indent(out) << "try __proto.writeStructEnd()" << endl; + indent(out) << "try __proto.writeFieldStop()" << '\n' << '\n'; + indent(out) << "try __proto.writeStructEnd()" << '\n'; block_close(out); - out << endl; + out << '\n'; } /** @@ -1396,12 +1394,12 @@ void t_swift_generator::generate_old_swift_struct_result_writer(ostream& out, t_ indent(out) << "private static func writeValue(__value: " << tstruct->get_name() << ", toProtocol __proto: TProtocol) throws"; block_open(out); - out << endl; + out << '\n'; string name = tstruct->get_name(); const vector& fields = tstruct->get_members(); vector::const_iterator f_iter; - indent(out) << "try __proto.writeStructBeginWithName(\"" << name << "\")" << endl; - out << endl; + indent(out) << "try __proto.writeStructBeginWithName(\"" << name << "\")" << '\n'; + out << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { t_field *tfield = *f_iter; @@ -1413,15 +1411,15 @@ void t_swift_generator::generate_old_swift_struct_result_writer(ostream& out, t_ indent(out) << "try __proto.writeFieldValue(result, " << "name: \"" << tfield->get_name() << "\", " << "type: " << type_to_enum(tfield->get_type()) << ", " - << "id: " << tfield->get_key() << ")" << endl; + << "id: " << tfield->get_key() << ")" << '\n'; block_close(out); } // Write the struct map - indent(out) << "try __proto.writeFieldStop()" << endl << endl; - indent(out) << "try __proto.writeStructEnd()" << endl; + indent(out) << "try __proto.writeFieldStop()" << '\n' << '\n'; + indent(out) << "try __proto.writeStructEnd()" << '\n'; block_close(out); - out << endl; + out << '\n'; } /** @@ -1440,50 +1438,50 @@ void t_swift_generator::generate_swift_struct_printable_extension(ostream& out, << (debug_descriptions_ ? "CustomDebugStringConvertible" : "CustomStringConvertible"); block_open(out); - out << endl; + out << '\n'; indent(out) << "public var description : String"; block_open(out); indent(out) << "var desc = \"" << tstruct->get_name(); if (!gen_cocoa_) { if (!tstruct->is_union()) { - out << "(\"" << endl; + out << "(\"" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end();) { indent(out) << "desc += \"" << (*f_iter)->get_name() << "=\\(String(describing: self." << maybe_escape_identifier((*f_iter)->get_name()) << "))"; if (++f_iter != fields.end()) { out << ", "; } - out << "\"" << endl; + out << "\"" << '\n'; } } else { - out << ".\"" << endl; - indent(out) << "switch self {" << endl; + out << ".\"" << '\n'; + indent(out) << "switch self {" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end();f_iter++) { indent(out) << "case ." << (*f_iter)->get_name() << "(let val): " << "desc += \"" << (*f_iter)->get_name() << "(val: \\(val))\"" - << endl; + << '\n'; } - indent(out) << "}" << endl; + indent(out) << "}" << '\n'; } } else { - out << "(\"" << endl; + out << "(\"" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end();) { indent(out) << "desc += \"" << (*f_iter)->get_name() << "=\\(self." << maybe_escape_identifier((*f_iter)->get_name()) << ")"; if (++f_iter != fields.end()) { out << ", "; } - out << "\"" << endl; + out << "\"" << '\n'; } - indent(out) << "desc += \")\"" << endl; + indent(out) << "desc += \")\"" << '\n'; } - indent(out) << "return desc" << endl; + indent(out) << "return desc" << '\n'; block_close(out); - out << endl; + out << '\n'; block_close(out); - out << endl; + out << '\n'; } /** @@ -1606,14 +1604,14 @@ void t_swift_generator::generate_swift_service_protocol(ostream& out, t_service* out << " : " << parent->get_name(); } block_open(out); - out << endl; + out << '\n'; vector functions = tservice->get_functions(); vector::iterator f_iter; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { function_docstring(out, *f_iter); - indent(out) << function_signature(*f_iter) << endl << endl; + indent(out) << function_signature(*f_iter) << '\n' << '\n'; } } else { @@ -1624,7 +1622,7 @@ void t_swift_generator::generate_swift_service_protocol(ostream& out, t_service* vector::iterator f_iter; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { - out << endl; + out << '\n'; indent(out) << function_signature(*f_iter) << " // exceptions: "; t_struct* xs = (*f_iter)->get_xceptions(); const vector& xceptions = xs->get_members(); @@ -1632,11 +1630,11 @@ void t_swift_generator::generate_swift_service_protocol(ostream& out, t_service* for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { out << type_name((*x_iter)->get_type()) + ", "; } - out << endl; + out << '\n'; } } block_close(out); - out << endl; + out << '\n'; } /** @@ -1652,7 +1650,7 @@ void t_swift_generator::generate_swift_service_protocol_async(ostream& out, t_se indent(out) << "public protocol " << tservice->get_name() << "Async"; block_open(out); - if (!gen_cocoa_) { out << endl; } + if (!gen_cocoa_) { out << '\n'; } vector functions = tservice->get_functions(); vector::iterator f_iter; @@ -1660,20 +1658,20 @@ void t_swift_generator::generate_swift_service_protocol_async(ostream& out, t_se if (!gen_cocoa_) { for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { async_function_docstring(out, *f_iter); - indent(out) << async_function_signature(*f_iter) << endl << endl; + indent(out) << async_function_signature(*f_iter) << '\n' << '\n'; } } else { for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { - out << endl; - indent(out) << async_function_signature(*f_iter) << endl; + out << '\n'; + indent(out) << async_function_signature(*f_iter) << '\n'; if (promise_kit_) { - indent(out) << promise_function_signature(*f_iter) << endl; + indent(out) << promise_function_signature(*f_iter) << '\n'; } // - out << endl; + out << '\n'; } } block_close(out); - out << endl; + out << '\n'; } /** @@ -1690,33 +1688,33 @@ void t_swift_generator::generate_swift_service_client(ostream& out, t_service* t out << " : " << ((parent == nullptr) ? "TClient" : parent->get_name() + "Client"); out << " /* , " << tservice->get_name() << " */"; block_open(out); - out << endl; + out << '\n'; } else { // a indent(out) << "public class " << tservice->get_name() << "Client /* : " << tservice->get_name() << " */"; block_open(out); - out << endl; + out << '\n'; - indent(out) << "let __inProtocol : TProtocol" << endl << endl; - indent(out) << "let __outProtocol : TProtocol" << endl << endl; + indent(out) << "let __inProtocol : TProtocol" << '\n' << '\n'; + indent(out) << "let __outProtocol : TProtocol" << '\n' << '\n'; indent(out) << "public init(inoutProtocol: TProtocol)"; block_open(out); - indent(out) << "__inProtocol = inoutProtocol" << endl; - indent(out) << "__outProtocol = inoutProtocol" << endl; + indent(out) << "__inProtocol = inoutProtocol" << '\n'; + indent(out) << "__outProtocol = inoutProtocol" << '\n'; block_close(out); - out << endl; + out << '\n'; indent(out) << "public init(inProtocol: TProtocol, outProtocol: TProtocol)"; block_open(out); - indent(out) << "__inProtocol = inProtocol" << endl; - indent(out) << "__outProtocol = outProtocol" << endl; + indent(out) << "__inProtocol = inProtocol" << '\n'; + indent(out) << "__outProtocol = outProtocol" << '\n'; block_close(out); - out << endl; + out << '\n'; } block_close(out); - out << endl; + out << '\n'; } /** @@ -1736,24 +1734,24 @@ void t_swift_generator::generate_swift_service_client_async(ostream& out, t_serv out << " /* , " << tservice->get_name() << " */"; block_open(out); - out << endl; + out << '\n'; } else { indent(out) << "public class " << tservice->get_name() << "AsyncClient /* : " << tservice->get_name() << " */"; block_open(out); - out << endl; + out << '\n'; - indent(out) << "let __protocolFactory : TProtocolFactory" << endl << endl; - indent(out) << "let __transportFactory : TAsyncTransportFactory" << endl << endl; + indent(out) << "let __protocolFactory : TProtocolFactory" << '\n' << '\n'; + indent(out) << "let __transportFactory : TAsyncTransportFactory" << '\n' << '\n'; indent(out) << "public init(protocolFactory: TProtocolFactory, transportFactory: TAsyncTransportFactory)"; block_open(out); - indent(out) << "__protocolFactory = protocolFactory" << endl; - indent(out) << "__transportFactory = transportFactory" << endl; + indent(out) << "__protocolFactory = protocolFactory" << '\n'; + indent(out) << "__transportFactory = transportFactory" << '\n'; block_close(out); - out << endl; + out << '\n'; } block_close(out); - out << endl; + out << '\n'; } /** @@ -1767,34 +1765,34 @@ void t_swift_generator::generate_swift_service_server(ostream& out, t_service* t indent(out) << "open class " << tservice->get_name() << "Processor /* " << tservice->get_name() << " */"; block_open(out); - out << endl; + out << '\n'; out << indent() << "typealias ProcessorHandlerDictionary = " - << "[String: (Int32, TProtocol, TProtocol, " << tservice->get_name() << ") throws -> Void]" << endl - << endl - << indent() << "public var service: " << tservice->get_name() << endl - << endl + << "[String: (Int32, TProtocol, TProtocol, " << tservice->get_name() << ") throws -> Void]" << '\n' + << '\n' + << indent() << "public var service: " << tservice->get_name() << '\n' + << '\n' << indent() << "public required init(service: " << tservice->get_name() << ")"; } else { indent(out) << "public class " << tservice->get_name() << "Processor : NSObject /* " << tservice->get_name() << " */"; block_open(out); - out << endl; + out << '\n'; out << indent() << "typealias ProcessorHandlerDictionary = " - << "[String: (Int, TProtocol, TProtocol, " << tservice->get_name() << ") throws -> Void]" << endl - << endl - << indent() << "let service : " << tservice->get_name() << endl - << endl + << "[String: (Int, TProtocol, TProtocol, " << tservice->get_name() << ") throws -> Void]" << '\n' + << '\n' + << indent() << "let service : " << tservice->get_name() << '\n' + << '\n' << indent() << "public init(service: " << tservice->get_name() << ")"; } block_open(out); - indent(out) << "self.service = service" << endl; + indent(out) << "self.service = service" << '\n'; block_close(out); - out << endl; + out << '\n'; block_close(out); - out << endl; + out << '\n'; } /** @@ -1831,7 +1829,7 @@ void t_swift_generator::generate_swift_service_client_send_function_implementati // Serialize the request indent(out) << "try outProtocol.writeMessageBegin(name: \"" << funname << "\", " << "type: " << (tfunction->is_oneway() ? ".oneway" : ".call") << ", " - << "sequenceID: 0)" << endl; + << "sequenceID: 0)" << '\n'; indent(out) << "let args = " << argsname << "("; @@ -1847,18 +1845,18 @@ void t_swift_generator::generate_swift_service_client_send_function_implementati out << ", "; } } - out << ")" << endl; - indent(out) << "try args.write(to: outProtocol)" << endl; - indent(out) << "try outProtocol.writeMessageEnd()" << endl; + out << ")" << '\n'; + indent(out) << "try args.write(to: outProtocol)" << '\n'; + indent(out) << "try outProtocol.writeMessageEnd()" << '\n'; } else { - out << endl; + out << '\n'; // Serialize the request indent(out) << "try __outProtocol.writeMessageBeginWithName(\"" << funname << "\", " << "type: " << (tfunction->is_oneway() ? ".ONEWAY" : ".CALL") << ", " - << "sequenceID: 0)" << endl; + << "sequenceID: 0)" << '\n'; - out << endl; + out << '\n'; indent(out) << "let __args = " << argsname << "("; @@ -1874,13 +1872,13 @@ void t_swift_generator::generate_swift_service_client_send_function_implementati out << ", "; } } - out << ")" << endl; - indent(out) << "try " << argsname << ".writeValue(__args, toProtocol: __outProtocol)" << endl << endl; - indent(out) << "try __outProtocol.writeMessageEnd()" << endl; + out << ")" << '\n'; + indent(out) << "try " << argsname << ".writeValue(__args, toProtocol: __outProtocol)" << '\n' << '\n'; + indent(out) << "try __outProtocol.writeMessageEnd()" << '\n'; } block_close(out); - out << endl; + out << '\n'; } /** @@ -1913,7 +1911,7 @@ void t_swift_generator::generate_swift_service_client_recv_function_implementati // check for an exception - indent(out) << "try inProtocol.readResultMessageBegin() " << endl; + indent(out) << "try inProtocol.readResultMessageBegin() " << '\n'; string resultname = function_result_helper_struct_type(tservice, tfunction); indent(out); @@ -1924,15 +1922,15 @@ void t_swift_generator::generate_swift_service_client_recv_function_implementati } string return_type_name = type_name(tfunction->get_returntype()); - out << "try " << resultname << ".read(from: inProtocol)" << endl; + out << "try " << resultname << ".read(from: inProtocol)" << '\n'; - indent(out) << "try inProtocol.readMessageEnd()" << endl << endl; + indent(out) << "try inProtocol.readMessageEnd()" << '\n' << '\n'; // Careful, only return _result if not a void function if (!tfunction->get_returntype()->is_void()) { indent(out) << "if let success = result.success"; block_open(out); - indent(out) << "return success" << endl; + indent(out) << "return success" << '\n'; block_close(out); } @@ -1943,14 +1941,14 @@ void t_swift_generator::generate_swift_service_client_recv_function_implementati for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { indent(out) << "if let " << (*x_iter)->get_name() << " = result." << (*x_iter)->get_name(); block_open(out); - indent(out) << "throw " << (*x_iter)->get_name() << endl; + indent(out) << "throw " << (*x_iter)->get_name() << '\n'; block_close(out); } // If you get here it's an exception, unless a void function if (!tfunction->get_returntype()->is_void()) { indent(out) << "throw TApplicationError(error: .missingResult(methodName: \"" - << tfunction->get_name() << "\"))" << endl; + << tfunction->get_name() << "\"))" << '\n'; } } else { if (needs_protocol) { @@ -1966,22 +1964,22 @@ void t_swift_generator::generate_swift_service_client_recv_function_implementati block_open(out); // check for an exception - out << endl; - indent(out) << "try __inProtocol.readResultMessageBegin() " << endl << endl; + out << '\n'; + indent(out) << "try __inProtocol.readResultMessageBegin() " << '\n' << '\n'; string resultname = function_result_helper_struct_type(tservice, tfunction); indent(out); if (!tfunction->get_returntype()->is_void() || !tfunction->get_xceptions()->get_members().empty()) { out << "let __result = "; } - out << "try " << resultname << ".readValueFromProtocol(__inProtocol)" << endl << endl; + out << "try " << resultname << ".readValueFromProtocol(__inProtocol)" << '\n' << '\n'; - indent(out) << "try __inProtocol.readMessageEnd()" << endl << endl; + indent(out) << "try __inProtocol.readMessageEnd()" << '\n' << '\n'; // Careful, only return _result if not a void function if (!tfunction->get_returntype()->is_void()) { indent(out) << "if let __success = __result.success"; block_open(out); - indent(out) << "return __success" << endl; + indent(out) << "return __success" << '\n'; block_close(out); } @@ -1992,24 +1990,24 @@ void t_swift_generator::generate_swift_service_client_recv_function_implementati for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { indent(out) << "if let " << (*x_iter)->get_name() << " = __result." << (*x_iter)->get_name(); block_open(out); - indent(out) << "throw " << (*x_iter)->get_name() << endl; + indent(out) << "throw " << (*x_iter)->get_name() << '\n'; block_close(out); } // If you get here it's an exception, unless a void function if (!tfunction->get_returntype()->is_void()) { - indent(out) << "throw NSError(" << endl; + indent(out) << "throw NSError(" << '\n'; indent_up(); - indent(out) << "domain: TApplicationErrorDomain, " << endl; - indent(out) << "code: Int(TApplicationError.MissingResult.rawValue)," << endl; - indent(out) << "userInfo: [TApplicationErrorMethodKey: \"" << tfunction->get_name() << "\"])" << endl; + indent(out) << "domain: TApplicationErrorDomain, " << '\n'; + indent(out) << "code: Int(TApplicationError.MissingResult.rawValue)," << '\n'; + indent(out) << "userInfo: [TApplicationErrorMethodKey: \"" << tfunction->get_name() << "\"])" << '\n'; indent_down(); } } // Close function block_close(out); - out << endl; + out << '\n'; } /** @@ -2035,7 +2033,7 @@ void t_swift_generator::generate_swift_service_client_send_function_invocation(o } } - out << ")" << endl; + out << ")" << '\n'; } /** @@ -2061,7 +2059,7 @@ void t_swift_generator::generate_swift_service_client_send_async_function_invoca out << ", " << (*f_iter)->get_name() << ": " << (*f_iter)->get_name(); } - out << ")" << endl; + out << ")" << '\n'; } /** @@ -2075,7 +2073,7 @@ void t_swift_generator::generate_swift_service_client_implementation(ostream& ou string name = tservice->get_name() + "Client"; indent(out) << "extension " << name << " : " << tservice->get_name(); block_open(out); - out << endl; + out << '\n'; // generate client method implementations vector functions = tservice->get_functions(); @@ -2092,28 +2090,28 @@ void t_swift_generator::generate_swift_service_client_implementation(ostream& ou indent(out) << "public " << function_signature(*f_iter); block_open(out); - if (gen_cocoa_) { out << endl; } + if (gen_cocoa_) { out << '\n'; } generate_swift_service_client_send_function_invocation(out, *f_iter); if (!gen_cocoa_) { - indent(out) << "try outProtocol.transport.flush()" << endl; + indent(out) << "try outProtocol.transport.flush()" << '\n'; } else { - out << endl; - indent(out) << "try __outProtocol.transport().flush()" << endl << endl; + out << '\n'; + indent(out) << "try __outProtocol.transport().flush()" << '\n' << '\n'; } if (!(*f_iter)->is_oneway()) { if ((*f_iter)->get_returntype()->is_void()) { - indent(out) << "try recv_" << (*f_iter)->get_name() << "()" << endl; + indent(out) << "try recv_" << (*f_iter)->get_name() << "()" << '\n'; } else { - indent(out) << "return try recv_" << (*f_iter)->get_name() << "()" << endl; + indent(out) << "return try recv_" << (*f_iter)->get_name() << "()" << '\n'; } } block_close(out); - out << endl; + out << '\n'; } block_close(out); - out << endl; + out << '\n'; } /** @@ -2131,7 +2129,7 @@ void t_swift_generator::generate_swift_service_client_async_implementation(ostre indent(out) << "extension " << name << " : " << protocol_name; block_open(out); - out << endl; + out << '\n'; // generate client method implementations vector functions = tservice->get_functions(); @@ -2146,10 +2144,10 @@ void t_swift_generator::generate_swift_service_client_async_implementation(ostre indent(out) << "public " << async_function_signature(*f_iter); block_open(out); - out << endl; - out << indent() << "let transport = factory.newTransport()" << endl - << indent() << "let proto = Protocol(on: transport)" << endl - << endl; + out << '\n'; + out << indent() << "let transport = factory.newTransport()" << '\n' + << indent() << "let proto = Protocol(on: transport)" << '\n' + << '\n'; out << indent() << "do"; block_open(out); @@ -2157,12 +2155,12 @@ void t_swift_generator::generate_swift_service_client_async_implementation(ostre generate_swift_service_client_send_async_function_invocation(out, *f_iter); indent_down(); - out << indent() << "} catch let error {" << endl; + out << indent() << "} catch let error {" << '\n'; indent_up(); - out << indent() << "completion(.error(error))" << endl; + out << indent() << "completion(.error(error))" << '\n'; block_close(out); - out << endl; + out << '\n'; bool ret_is_void = (*f_iter)->get_returntype()->is_void(); bool is_oneway = (*f_iter)->is_oneway(); @@ -2170,10 +2168,10 @@ void t_swift_generator::generate_swift_service_client_async_implementation(ostre string error_completion_call = "completion(.error(error))"; indent(out) << "transport.flush"; block_open(out); - out << indent() << "(trans, error) in" << endl << endl; + out << indent() << "(trans, error) in" << '\n' << '\n'; out << indent() << "if let error = error"; block_open(out); - out << indent() << error_completion_call << endl; + out << indent() << error_completion_call << '\n'; block_close(out); if (!is_oneway) { @@ -2183,24 +2181,24 @@ void t_swift_generator::generate_swift_service_client_async_implementation(ostre if (!ret_is_void) { out << "let result = "; } - out << "try self.recv_" << (*f_iter)->get_name() << "(on: proto)" << endl; + out << "try self.recv_" << (*f_iter)->get_name() << "(on: proto)" << '\n'; - out << indent() << (ret_is_void ? "completion(.success(Void()))" : "completion(.success(result))") << endl; + out << indent() << (ret_is_void ? "completion(.success(Void()))" : "completion(.success(result))") << '\n'; indent_down(); - out << indent() << "} catch let error {" << endl; + out << indent() << "} catch let error {" << '\n'; indent_up(); - out << indent() << error_completion_call << endl; + out << indent() << error_completion_call << '\n'; block_close(out); } else { - out << indent() << "completion(.success(Void()))" << endl; + out << indent() << "completion(.success(Void()))" << '\n'; } block_close(out); block_close(out); } block_close(out); - out << endl; + out << '\n'; } void t_swift_generator::generate_old_swift_service_client_async_implementation(ostream& out, @@ -2211,7 +2209,7 @@ void t_swift_generator::generate_old_swift_service_client_async_implementation(o indent(out) << "extension " << name << " : " << protocol_name; block_open(out); - out << endl; + out << '\n'; // generate client method implementations vector functions = tservice->get_functions(); @@ -2226,19 +2224,19 @@ void t_swift_generator::generate_old_swift_service_client_async_implementation(o indent(out) << "public " << async_function_signature(*f_iter); block_open(out); - out << endl; + out << '\n'; - out << indent() << "let __transport = __transportFactory.newTransport()" << endl - << indent() << "let __protocol = __protocolFactory.newProtocolOnTransport(__transport)" << endl - << endl; + out << indent() << "let __transport = __transportFactory.newTransport()" << '\n' + << indent() << "let __protocol = __protocolFactory.newProtocolOnTransport(__transport)" << '\n' + << '\n'; generate_swift_service_client_send_async_function_invocation(out, *f_iter); - out << endl; + out << '\n'; indent(out) << "__transport.flushWithCompletion("; if ((*f_iter)->is_oneway()) { - out << "success, failure: failure)" << endl; + out << "success, failure: failure)" << '\n'; } else { block_open(out); @@ -2249,25 +2247,25 @@ void t_swift_generator::generate_old_swift_service_client_async_implementation(o if (!(*f_iter)->get_returntype()->is_void()) { out << "let result = "; } - out << "try self.recv_" << (*f_iter)->get_name() << "(__protocol)" << endl; + out << "try self.recv_" << (*f_iter)->get_name() << "(__protocol)" << '\n'; out << indent() << "success("; if (!(*f_iter)->get_returntype()->is_void()) { out << "result"; } - out << ")" << endl; + out << ")" << '\n'; block_close(out); indent(out) << "catch let error"; block_open(out); - indent(out) << "failure(error as NSError)" << endl; + indent(out) << "failure(error as NSError)" << '\n'; block_close(out); block_close(out); - indent(out) << ", failure: failure)" << endl; + indent(out) << ", failure: failure)" << '\n'; } block_close(out); - out << endl; + out << '\n'; // Promise function if (promise_kit_) { @@ -2275,17 +2273,17 @@ void t_swift_generator::generate_old_swift_service_client_async_implementation(o indent(out) << "public " << promise_function_signature(*f_iter); block_open(out); - out << indent() << "let (__promise, __fulfill, __reject) = Promise<" << type_name((*f_iter)->get_returntype()) << ">.pendingPromise()" << endl << endl - << indent() << "let __transport = __transportFactory.newTransport()" << endl - << indent() << "let __protocol = __protocolFactory.newProtocolOnTransport(__transport)" << endl - << endl; + out << indent() << "let (__promise, __fulfill, __reject) = Promise<" << type_name((*f_iter)->get_returntype()) << ">.pendingPromise()" << '\n' << '\n' + << indent() << "let __transport = __transportFactory.newTransport()" << '\n' + << indent() << "let __protocol = __protocolFactory.newProtocolOnTransport(__transport)" << '\n' + << '\n'; generate_swift_service_client_send_async_function_invocation(out, *f_iter); - out << endl; + out << '\n'; indent(out) << "__transport.flushWithCompletion("; if ((*f_iter)->is_oneway()) { - out << "{ __fulfill() }, failure: { __reject($0) })" << endl; + out << "{ __fulfill() }, failure: { __reject($0) })" << '\n'; } else { block_open(out); @@ -2296,37 +2294,37 @@ void t_swift_generator::generate_old_swift_service_client_async_implementation(o if (!(*f_iter)->get_returntype()->is_void()) { out << "let result = "; } - out << "try self.recv_" << (*f_iter)->get_name() << "(__protocol)" << endl; + out << "try self.recv_" << (*f_iter)->get_name() << "(__protocol)" << '\n'; out << indent() << "__fulfill("; if (!(*f_iter)->get_returntype()->is_void()) { out << "result"; } - out << ")" << endl; + out << ")" << '\n'; block_close(out); indent(out) << "catch let error"; block_open(out); - indent(out) << "__reject(error)" << endl; + indent(out) << "__reject(error)" << '\n'; block_close(out); block_close(out); - indent(out) << ", failure: { error in " << endl; + indent(out) << ", failure: { error in " << '\n'; indent_up(); - indent(out) << "__reject(error)" << endl; + indent(out) << "__reject(error)" << '\n'; indent_down(); - indent(out) << "})" << endl; + indent(out) << "})" << '\n'; } - indent(out) << "return __promise" << endl; + indent(out) << "return __promise" << '\n'; block_close(out); - out << endl; + out << '\n'; } } block_close(out); - out << endl; + out << '\n'; } /** @@ -2345,12 +2343,12 @@ void t_swift_generator::generate_swift_service_server_implementation(ostream& ou indent(out) << "extension " << name << " : TProcessor"; block_open(out); - out << endl; + out << '\n'; indent(out) << "static let processorHandlers" << (gen_cocoa_ ? " " : "") << ": ProcessorHandlerDictionary ="; block_open(out); - out << endl; - out << indent() << "var processorHandlers = ProcessorHandlerDictionary()" << endl << endl; + out << '\n'; + out << indent() << "var processorHandlers = ProcessorHandlerDictionary()" << '\n' << '\n'; // generate method map for routing incoming calls vector functions = tservice->get_functions(); @@ -2361,25 +2359,25 @@ void t_swift_generator::generate_swift_service_server_implementation(ostream& ou string args_type = function_args_helper_struct_type(tservice, *f_iter); - out << indent() << "processorHandlers[\"" << tfunction->get_name() << "\"] = { sequenceID, inProtocol, outProtocol, handler in" << endl - << endl; + out << indent() << "processorHandlers[\"" << tfunction->get_name() << "\"] = { sequenceID, inProtocol, outProtocol, handler in" << '\n' + << '\n'; indent_up(); if (!gen_cocoa_) { - out << indent() << "let args = try " << args_type << ".read(from: inProtocol)" << endl - << endl - << indent() << "try inProtocol.readMessageEnd()" << endl - << endl; + out << indent() << "let args = try " << args_type << ".read(from: inProtocol)" << '\n' + << '\n' + << indent() << "try inProtocol.readMessageEnd()" << '\n' + << '\n'; } else { - out << indent() << "let args = try " << args_type << ".readValueFromProtocol(inProtocol)" << endl - << endl - << indent() << "try inProtocol.readMessageEnd()" << endl - << endl; + out << indent() << "let args = try " << args_type << ".readValueFromProtocol(inProtocol)" << '\n' + << '\n' + << indent() << "try inProtocol.readMessageEnd()" << '\n' + << '\n'; } if (!tfunction->is_oneway() ) { string result_type = function_result_helper_struct_type(tservice, tfunction); - indent(out) << "var result = " << result_type << "()" << endl; + indent(out) << "var result = " << result_type << "()" << '\n'; indent(out) << "do"; block_open(out); @@ -2406,7 +2404,7 @@ void t_swift_generator::generate_swift_service_server_implementation(ostream& ou } } - out << ")" << endl; + out << ")" << '\n'; block_close(out); t_struct* xs = tfunction->get_xceptions(); @@ -2423,37 +2421,37 @@ void t_swift_generator::generate_swift_service_server_implementation(ostream& ou } out << (*x_iter)->get_type()->get_name(); - out << " { result." << (*x_iter)->get_name() << " = error }" << endl; + out << " { result." << (*x_iter)->get_name() << " = error }" << '\n'; } - indent(out) << "catch let error { throw error }" << endl; - out << endl; + indent(out) << "catch let error { throw error }" << '\n'; + out << '\n'; if (!tfunction->is_oneway()) { - out << indent() << "try outProtocol.writeMessageBegin(name: \"" << tfunction->get_name() << "\", type: .reply, sequenceID: sequenceID)" << endl - << indent() << "try result.write(to: outProtocol)" << endl - << indent() << "try outProtocol.writeMessageEnd()" << endl - << indent() << "try outProtocol.transport.flush()" << endl; + out << indent() << "try outProtocol.writeMessageBegin(name: \"" << tfunction->get_name() << "\", type: .reply, sequenceID: sequenceID)" << '\n' + << indent() << "try result.write(to: outProtocol)" << '\n' + << indent() << "try outProtocol.writeMessageEnd()" << '\n' + << indent() << "try outProtocol.transport.flush()" << '\n'; } } else { for (x_iter = xfields.begin(); x_iter != xfields.end(); ++x_iter) { indent(out) << "catch let error as " << (*x_iter)->get_type()->get_name(); block_open(out); - indent(out) << "result." << (*x_iter)->get_name() << " = error" << endl; + indent(out) << "result." << (*x_iter)->get_name() << " = error" << '\n'; block_close(out); } indent(out) << "catch let error"; block_open(out); - out << indent() << "throw error" << endl; + out << indent() << "throw error" << '\n'; block_close(out); - out << endl; + out << '\n'; if (!tfunction->is_oneway()) { - out << indent() << "try outProtocol.writeMessageBeginWithName(\"" << tfunction->get_name() << "\", type: .REPLY, sequenceID: sequenceID)" << endl - << indent() << "try " << result_type << ".writeValue(result, toProtocol: outProtocol)" << endl - << indent() << "try outProtocol.writeMessageEnd()" << endl; + out << indent() << "try outProtocol.writeMessageBeginWithName(\"" << tfunction->get_name() << "\", type: .REPLY, sequenceID: sequenceID)" << '\n' + << indent() << "try " << result_type << ".writeValue(result, toProtocol: outProtocol)" << '\n' + << indent() << "try outProtocol.writeMessageEnd()" << '\n'; } } } @@ -2461,11 +2459,11 @@ void t_swift_generator::generate_swift_service_server_implementation(ostream& ou } - indent(out) << "return processorHandlers" << endl; + indent(out) << "return processorHandlers" << '\n'; block_close(out,false); - out << "()" << endl; - out << endl; + out << "()" << '\n'; + out << '\n'; if (!gen_cocoa_) { indent(out) << "public func process(on inProtocol: TProtocol, outProtocol: TProtocol) throws"; @@ -2474,47 +2472,47 @@ void t_swift_generator::generate_swift_service_server_implementation(ostream& ou } block_open(out); - out << endl; - out << indent() << "let (messageName, _, sequenceID) = try inProtocol.readMessageBegin()" << endl - << endl + out << '\n'; + out << indent() << "let (messageName, _, sequenceID) = try inProtocol.readMessageBegin()" << '\n' + << '\n' << indent() << "if let processorHandler = " << name << ".processorHandlers[messageName]"; block_open(out); out << indent() << "do"; block_open(out); - out << indent() << "try processorHandler(sequenceID, inProtocol, outProtocol, service)" << endl; + out << indent() << "try processorHandler(sequenceID, inProtocol, outProtocol, service)" << '\n'; block_close(out); if (!gen_cocoa_) { out << indent() << "catch let error as TApplicationError"; block_open(out); - out << indent() << "try outProtocol.writeException(messageName: messageName, sequenceID: sequenceID, ex: error)" << endl - << indent() << "try outProtocol.transport.flush()" << endl; + out << indent() << "try outProtocol.writeException(messageName: messageName, sequenceID: sequenceID, ex: error)" << '\n' + << indent() << "try outProtocol.transport.flush()" << '\n'; block_close(out); block_close(out); out << indent() << "else"; block_open(out); - out << indent() << "try inProtocol.skip(type: .struct)" << endl - << indent() << "try inProtocol.readMessageEnd()" << endl - << indent() << "let ex = TApplicationError(error: .unknownMethod(methodName: messageName))" << endl - << indent() << "try outProtocol.writeException(messageName: messageName, sequenceID: sequenceID, ex: ex)" << endl - << indent() << "try outProtocol.transport.flush()" << endl; + out << indent() << "try inProtocol.skip(type: .struct)" << '\n' + << indent() << "try inProtocol.readMessageEnd()" << '\n' + << indent() << "let ex = TApplicationError(error: .unknownMethod(methodName: messageName))" << '\n' + << indent() << "try outProtocol.writeException(messageName: messageName, sequenceID: sequenceID, ex: ex)" << '\n' + << indent() << "try outProtocol.transport.flush()" << '\n'; } else { out << indent() << "catch let error as NSError"; block_open(out); - out << indent() << "try outProtocol.writeExceptionForMessageName(messageName, sequenceID: sequenceID, ex: error)" << endl; + out << indent() << "try outProtocol.writeExceptionForMessageName(messageName, sequenceID: sequenceID, ex: error)" << '\n'; block_close(out); block_close(out); out << indent() << "else"; block_open(out); - out << indent() << "try inProtocol.skipType(.STRUCT)" << endl - << indent() << "try inProtocol.readMessageEnd()" << endl - << indent() << "try outProtocol.writeExceptionForMessageName(messageName," << endl; + out << indent() << "try inProtocol.skipType(.STRUCT)" << '\n' + << indent() << "try inProtocol.readMessageEnd()" << '\n' + << indent() << "try outProtocol.writeExceptionForMessageName(messageName," << '\n'; indent_up(); - out << indent() << "sequenceID: sequenceID," << endl - << indent() << "ex: NSError(" << endl; + out << indent() << "sequenceID: sequenceID," << '\n' + << indent() << "ex: NSError(" << '\n'; indent_up(); - out << indent() << "domain: TApplicationErrorDomain, " << endl - << indent() << "code: Int(TApplicationError.UnknownMethod.rawValue), " << endl - << indent() << "userInfo: [TApplicationErrorMethodKey: messageName]))" << endl; + out << indent() << "domain: TApplicationErrorDomain, " << '\n' + << indent() << "code: Int(TApplicationError.UnknownMethod.rawValue), " << '\n' + << indent() << "userInfo: [TApplicationErrorMethodKey: messageName]))" << '\n'; indent_down(); indent_down(); } @@ -2522,7 +2520,7 @@ void t_swift_generator::generate_swift_service_server_implementation(ostream& ou block_close(out); block_close(out); block_close(out); - out << endl; + out << '\n'; } /** @@ -2812,27 +2810,27 @@ void t_swift_generator::function_docstring(ostream& out, t_function* tfunction) // Description string doc = tfunction->get_doc(); generate_docstring(out, doc); - indent(out) << "///" << endl; + indent(out) << "///" << '\n'; // Parameters const vector& fields = tfunction->get_arglist()->get_members(); vector::const_iterator f_iter; if (!fields.empty()) { - indent(out) << "/// - Parameters:" << endl; + indent(out) << "/// - Parameters:" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { indent(out) << "/// - " << (*f_iter)->get_name() << ": "; string doc = (*f_iter)->get_doc(); if (!doc.empty() && doc[doc.length()-1] == '\n') { doc.erase(doc.length()-1); } - out << doc << endl; + out << doc << '\n'; } } // Returns t_type* ttype = tfunction->get_returntype(); if (!ttype->is_void()) { - indent(out) << "/// - Returns: " << type_name(ttype) << endl; + indent(out) << "/// - Returns: " << type_name(ttype) << '\n'; } // Throws @@ -2845,7 +2843,7 @@ void t_swift_generator::function_docstring(ostream& out, t_function* tfunction) if (*x_iter != xceptions.back()) { out << ", "; } } - out << endl; + out << '\n'; } /** @@ -2865,20 +2863,20 @@ void t_swift_generator::async_function_docstring(ostream& out, t_function* tfunc // Description string doc = tfunction->get_doc(); generate_docstring(out, doc); - indent(out) << "///" << endl; + indent(out) << "///" << '\n'; // Parameters const vector& fields = tfunction->get_arglist()->get_members(); vector::const_iterator f_iter; if (!fields.empty()) { - indent(out) << "/// - Parameters:" << endl; + indent(out) << "/// - Parameters:" << '\n'; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { indent(out) << "/// - " << (*f_iter)->get_name() << ": "; string doc = (*f_iter)->get_doc(); if (!doc.empty() && doc[doc.length()-1] == '\n') { doc.erase(doc.length()-1); } - out << doc << endl; + out << doc << '\n'; } } @@ -2894,7 +2892,7 @@ void t_swift_generator::async_function_docstring(ostream& out, t_function* tfunc out << ", "; } } - out << endl; + out << '\n'; } /** diff --git a/compiler/cpp/src/thrift/generate/t_xml_generator.cc b/compiler/cpp/src/thrift/generate/t_xml_generator.cc index 68675cfa157..86c2718cb25 100644 --- a/compiler/cpp/src/thrift/generate/t_xml_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_xml_generator.cc @@ -39,9 +39,6 @@ using std::vector; using std::stack; using std::set; -static const string endl = "\n"; -static const string quot = "\""; - static const string default_ns_prefix = "http://thrift.apache.org/xml/ns/"; /** @@ -196,7 +193,7 @@ void t_xml_generator::write_xml_comment(string msg) { close_top_element(); // TODO: indent any EOLs that may occur with msg // TODO: proper msg escaping needed? - f_xml_ << indent() << "" << endl; + f_xml_ << indent() << "" << '\n'; top_element_is_empty = false; } @@ -204,7 +201,7 @@ void t_xml_generator::close_top_element() { if( top_element_is_open) { top_element_is_open = false; if (elements_.size() > 0 && top_element_is_empty) { - f_xml_ << ">" << endl; + f_xml_ << ">" << '\n'; } } } @@ -224,9 +221,9 @@ void t_xml_generator::write_element_start(string name) { void t_xml_generator::write_element_end() { indent_down(); if (top_element_is_empty && top_element_is_open) { - f_xml_ << " />" << endl; + f_xml_ << " />" << '\n'; } else { - f_xml_ << indent() << "" << endl; + f_xml_ << indent() << "" << '\n'; } top_element_is_empty = false; elements_.pop(); @@ -248,7 +245,7 @@ void t_xml_generator::write_element_string(string name, string val) { top_element_is_empty = false; f_xml_ << indent() << "<" << name << ">" << escape_xml_string(val) << "" - << endl; + << '\n'; } string t_xml_generator::escape_xml_string(const string& input) { @@ -511,7 +508,7 @@ void t_xml_generator::write_const_value(t_const_value* value) { default: indent_up(); - f_xml_ << indent() << "" << endl; + f_xml_ << indent() << "" << '\n'; indent_down(); break; } diff --git a/compiler/cpp/src/thrift/generate/t_xsd_generator.cc b/compiler/cpp/src/thrift/generate/t_xsd_generator.cc index 1f58f3a619f..8dd84f0e13c 100644 --- a/compiler/cpp/src/thrift/generate/t_xsd_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_xsd_generator.cc @@ -36,8 +36,6 @@ using std::string; using std::stringstream; using std::vector; -static const string endl = "\n"; // avoid ostream << std::endl flushes - /** * XSD generator, creates an XSD for the base types etc. * @@ -121,22 +119,22 @@ void t_xsd_generator::init_generator() { string f_php_name = get_out_dir() + program_->get_name() + "_xsd.php"; f_php_.open(f_php_name.c_str()); - f_php_ << "" << endl; + f_php_ << "?>" << '\n'; f_php_.close(); } void t_xsd_generator::generate_typedef(t_typedef* ttypedef) { - indent(s_xsd_types_) << "get_name() << "\">" << endl; + indent(s_xsd_types_) << "get_name() << "\">" << '\n'; indent_up(); indent(s_xsd_types_) << "get_type()) << "\" />" - << endl; + << '\n'; indent_down(); - indent(s_xsd_types_) << "" << endl << endl; + indent(s_xsd_types_) << "" << '\n' << '\n'; } void t_xsd_generator::generate_struct(t_struct* tstruct) { @@ -144,12 +142,12 @@ void t_xsd_generator::generate_struct(t_struct* tstruct) { const vector& members = tstruct->get_members(); bool xsd_all = tstruct->get_xsd_all(); - indent(s_xsd_types_) << "get_name() << "\">" << endl; + indent(s_xsd_types_) << "get_name() << "\">" << '\n'; indent_up(); if (xsd_all) { - indent(s_xsd_types_) << "" << endl; + indent(s_xsd_types_) << "" << '\n'; } else { - indent(s_xsd_types_) << "" << endl; + indent(s_xsd_types_) << "" << '\n'; } indent_up(); @@ -164,12 +162,12 @@ void t_xsd_generator::generate_struct(t_struct* tstruct) { indent_down(); if (xsd_all) { - indent(s_xsd_types_) << "" << endl; + indent(s_xsd_types_) << "" << '\n'; } else { - indent(s_xsd_types_) << "" << endl; + indent(s_xsd_types_) << "" << '\n'; } indent_down(); - indent(s_xsd_types_) << "" << endl << endl; + indent(s_xsd_types_) << "" << '\n' << '\n'; } void t_xsd_generator::generate_element(ostream& out, @@ -185,15 +183,15 @@ void t_xsd_generator::generate_element(ostream& out, string snillable = nillable ? " nillable=\"true\"" : ""; if (ttype->is_void() || ttype->is_list()) { - indent(out) << "" << endl; + indent(out) << "" << '\n'; indent_up(); if (attrs == nullptr && ttype->is_void()) { - indent(out) << "" << endl; + indent(out) << "" << '\n'; } else { - indent(out) << "" << endl; + indent(out) << "" << '\n'; indent_up(); if (ttype->is_list()) { - indent(out) << "" << endl; + indent(out) << "" << '\n'; indent_up(); string subname; t_type* subtype = ((t_list*)ttype)->get_elem_type(); @@ -203,55 +201,55 @@ void t_xsd_generator::generate_element(ostream& out, subname = type_name(subtype); } f_php_ << "$GLOBALS['" << program_->get_name() << "_xsd_elt_" << name << "'] = '" << subname - << "';" << endl; + << "';" << '\n'; generate_element(out, subname, subtype, nullptr, false, false, true); indent_down(); - indent(out) << "" << endl; - indent(out) << "" << endl; + indent(out) << "" << '\n'; + indent(out) << "" << '\n'; } if (attrs != nullptr) { const vector& members = attrs->get_members(); vector::const_iterator a_iter; for (a_iter = members.begin(); a_iter != members.end(); ++a_iter) { indent(out) << "get_name() << "\" type=\"" - << type_name((*a_iter)->get_type()) << "\" />" << endl; + << type_name((*a_iter)->get_type()) << "\" />" << '\n'; } } indent_down(); - indent(out) << "" << endl; + indent(out) << "" << '\n'; } indent_down(); - indent(out) << "" << endl; + indent(out) << "" << '\n'; } else { if (attrs == nullptr) { indent(out) << "" - << endl; + << '\n'; } else { // Wow, all this work for a SIMPLE TYPE with attributes?!?!?! indent(out) << "" - << endl; + << '\n'; indent_up(); - indent(out) << "" << endl; + indent(out) << "" << '\n'; indent_up(); - indent(out) << "" << endl; + indent(out) << "" << '\n'; indent_up(); - indent(out) << "" << endl; + indent(out) << "" << '\n'; indent_up(); const vector& members = attrs->get_members(); vector::const_iterator a_iter; for (a_iter = members.begin(); a_iter != members.end(); ++a_iter) { indent(out) << "get_name() << "\" type=\"" - << type_name((*a_iter)->get_type()) << "\" />" << endl; + << type_name((*a_iter)->get_type()) << "\" />" << '\n'; } indent_down(); - indent(out) << "" << endl; + indent(out) << "" << '\n'; indent_down(); - indent(out) << "" << endl; + indent(out) << "" << '\n'; indent_down(); - indent(out) << "" << endl; + indent(out) << "" << '\n'; indent_down(); - indent(out) << "" << endl; + indent(out) << "" << '\n'; } } } @@ -274,10 +272,10 @@ void t_xsd_generator::generate_service(t_service* tservice) { } // Print the XSD header - f_xsd_ << "" << endl - << "" << endl + f_xsd_ << "" << '\n' + << "" << '\n' << xml_autogen_comment() - << endl; + << '\n'; // Print out the type definitions indent(f_xsd_) << s_xsd_types_.str(); @@ -292,7 +290,7 @@ void t_xsd_generator::generate_service(t_service* tservice) { string elemname = (*f_iter)->get_name() + "_response"; t_type* returntype = (*f_iter)->get_returntype(); generate_element(f_xsd_, elemname, returntype); - f_xsd_ << endl; + f_xsd_ << '\n'; t_struct* xs = (*f_iter)->get_xceptions(); const std::vector& xceptions = xs->get_members(); @@ -308,7 +306,7 @@ void t_xsd_generator::generate_service(t_service* tservice) { } // Close the XSD document - f_xsd_ << endl << "" << endl; + f_xsd_ << '\n' << "" << '\n'; f_xsd_.close(); } diff --git a/compiler/cpp/src/thrift/main.cc b/compiler/cpp/src/thrift/main.cc index 5177076adf7..56c5811013d 100644 --- a/compiler/cpp/src/thrift/main.cc +++ b/compiler/cpp/src/thrift/main.cc @@ -373,7 +373,12 @@ string include_file(string filename) { } // Uh oh - pwarning(0, "Could not find include file %s\n", filename.c_str()); + if (g_strict >= 192) { + // On strict mode this should be failure instead of warning + failure("Could not find include file %s", filename.c_str()); + } else { + pwarning(0, "Could not find include file %s\n", filename.c_str()); + } return std::string(); } diff --git a/compiler/cpp/src/thrift/parse/t_doc.h b/compiler/cpp/src/thrift/parse/t_doc.h index 0df893eb263..4033bc78d68 100644 --- a/compiler/cpp/src/thrift/parse/t_doc.h +++ b/compiler/cpp/src/thrift/parse/t_doc.h @@ -47,6 +47,8 @@ class t_doc { bool has_doc() { return has_doc_; } + virtual void validate() const { ; } + private: std::string doc_; bool has_doc_; diff --git a/compiler/cpp/src/thrift/parse/t_field.h b/compiler/cpp/src/thrift/parse/t_field.h index 928fdcf93ef..3346722646a 100644 --- a/compiler/cpp/src/thrift/parse/t_field.h +++ b/compiler/cpp/src/thrift/parse/t_field.h @@ -41,7 +41,7 @@ class t_field : public t_doc { : type_(type), name_(name), key_(0), - req_(T_OPT_IN_REQ_OUT), + req_(T_OPT_IN_REQ_OUT), value_(nullptr), xsd_optional_(false), xsd_nillable_(false), diff --git a/compiler/cpp/src/thrift/parse/t_function.h b/compiler/cpp/src/thrift/parse/t_function.h index a3b6f48e3e2..abe29039f95 100644 --- a/compiler/cpp/src/thrift/parse/t_function.h +++ b/compiler/cpp/src/thrift/parse/t_function.h @@ -83,6 +83,28 @@ class t_function : public t_doc { std::map> annotations_; + void validate() const override { + get_returntype()->validate(); + +#ifndef ALLOW_EXCEPTIONS_AS_TYPE + if (get_returntype()->get_true_type()->is_xception()) { + failure("method %s(): exception type \"%s\" cannot be used as function return", get_name().c_str(), get_returntype()->get_name().c_str()); + } +#endif + + std::vector::const_iterator it; + std::vector list = get_arglist()->get_members(); + for(it=list.begin(); it != list.end(); ++it) { + (*it)->get_type()->validate(); + +#ifndef ALLOW_EXCEPTIONS_AS_TYPE + if( (*it)->get_type()->get_true_type()->is_xception()) { + failure("method %s(): exception type \"%s\" cannot be used as function argument %s", get_name().c_str(), (*it)->get_type()->get_name().c_str(), (*it)->get_name().c_str()); + } +#endif + } + } + private: t_type* returntype_; std::string name_; diff --git a/compiler/cpp/src/thrift/parse/t_list.h b/compiler/cpp/src/thrift/parse/t_list.h index f0b896d0cb0..9c1dfadea27 100644 --- a/compiler/cpp/src/thrift/parse/t_list.h +++ b/compiler/cpp/src/thrift/parse/t_list.h @@ -34,6 +34,14 @@ class t_list : public t_container { bool is_list() const override { return true; } + void validate() const override { +#ifndef ALLOW_EXCEPTIONS_AS_TYPE + if( get_elem_type()->get_true_type()->is_xception()) { + failure("exception type \"%s\" cannot be used inside a list", get_elem_type()->get_name().c_str()); + } +#endif + } + 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 9614e6849c6..6ec58cfbb13 100644 --- a/compiler/cpp/src/thrift/parse/t_map.h +++ b/compiler/cpp/src/thrift/parse/t_map.h @@ -37,6 +37,17 @@ class t_map : public t_container { bool is_map() const override { return true; } + void validate() const override { +#ifndef ALLOW_EXCEPTIONS_AS_TYPE + if( get_key_type()->get_true_type()->is_xception()) { + failure("exception type \"%s\" cannot be used inside a map", get_key_type()->get_name().c_str()); + } + if( get_val_type()->get_true_type()->is_xception()) { + failure("exception type \"%s\" cannot be used inside a map", get_val_type()->get_name().c_str()); + } +#endif + } + private: t_type* key_type_; t_type* val_type_; diff --git a/compiler/cpp/src/thrift/parse/t_set.h b/compiler/cpp/src/thrift/parse/t_set.h index c0d4a35c190..8f7599a5a60 100644 --- a/compiler/cpp/src/thrift/parse/t_set.h +++ b/compiler/cpp/src/thrift/parse/t_set.h @@ -36,6 +36,14 @@ class t_set : public t_container { bool is_set() const override { return true; } + void validate() const override { +#ifndef ALLOW_EXCEPTIONS_AS_TYPE + if( get_elem_type()->get_true_type()->is_xception()) { + failure("exception type \"%s\" cannot be used inside a set", get_elem_type()->get_name().c_str()); + } +#endif + } + 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 d990eadd57d..8b33ee6c4b3 100644 --- a/compiler/cpp/src/thrift/parse/t_struct.h +++ b/compiler/cpp/src/thrift/parse/t_struct.h @@ -112,9 +112,8 @@ class t_struct : public t_type { const members_type& get_sorted_members() const { return members_in_id_order_; } bool is_struct() const override { return !is_xception_; } - bool is_xception() const override { return is_xception_; } - + bool is_method_xcepts() const override { return is_method_xcepts_; } bool is_union() const { return is_union_; } t_field* get_field_by_name(std::string field_name) { @@ -131,6 +130,30 @@ class t_struct : public t_type { return nullptr; } + void validate() const override { + std::string what = "struct"; + if( is_union()) { + what = "union"; + } + if( is_xception()) { + what = "exception"; + } + + std::vector::const_iterator it; + std::vector list = get_members(); + for(it=list.begin(); it != list.end(); ++it) { + (*it)->get_type()->validate(); + +#ifndef ALLOW_EXCEPTIONS_AS_TYPE + if (!is_method_xcepts_) { // this is in fact the only legal usage for any exception type + if( (*it)->get_type()->get_true_type()->is_xception()) { + failure("%s %s: exception type \"%s\" cannot be used as member field type %s", what.c_str(), get_name().c_str(), (*it)->get_type()->get_name().c_str(), (*it)->get_name().c_str()); + } + } +#endif + } + } + private: members_type members_; members_type members_in_id_order_; diff --git a/compiler/cpp/src/thrift/parse/t_type.h b/compiler/cpp/src/thrift/parse/t_type.h index f4082426c8e..d087601aeca 100644 --- a/compiler/cpp/src/thrift/parse/t_type.h +++ b/compiler/cpp/src/thrift/parse/t_type.h @@ -26,6 +26,8 @@ #include #include +#define ALLOW_EXCEPTIONS_AS_TYPE + class t_program; /** @@ -54,6 +56,7 @@ class t_type : public t_doc { virtual bool is_enum() const { return false; } virtual bool is_struct() const { return false; } virtual bool is_xception() const { return false; } + virtual bool is_method_xcepts() const { return false; } virtual bool is_container() const { return false; } virtual bool is_list() const { return false; } virtual bool is_set() const { return false; } diff --git a/compiler/cpp/src/thrift/version.h b/compiler/cpp/src/thrift/version.h index 65e0f43684b..f7419838e8b 100644 --- a/compiler/cpp/src/thrift/version.h +++ b/compiler/cpp/src/thrift/version.h @@ -24,6 +24,6 @@ #pragma once #endif // _MSC_VER -#define THRIFT_VERSION "0.20.0" +#define THRIFT_VERSION "0.22.0" #endif // _THRIFT_VERSION_H_ diff --git a/compiler/cpp/test/Makefile.am b/compiler/cpp/test/Makefile.am index 10efd073767..6d4d09e938d 100644 --- a/compiler/cpp/test/Makefile.am +++ b/compiler/cpp/test/Makefile.am @@ -23,5 +23,8 @@ AUTOMAKE_OPTIONS = subdir-objects serial-tests nostdinc +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + AM_CPPFLAGS = -I$(top_srcdir)/compiler/cpp/src AM_CXXFLAGS = -Wall -Wextra -pedantic diff --git a/compiler/cpp/test/compiler/staleness_check.py b/compiler/cpp/test/compiler/staleness_check.py index 6b67798d6a4..4dcec15ce89 100755 --- a/compiler/cpp/test/compiler/staleness_check.py +++ b/compiler/cpp/test/compiler/staleness_check.py @@ -17,7 +17,6 @@ # specific language governing permissions and limitations # under the License. # -from __future__ import print_function import os import shutil import subprocess diff --git a/compiler/cpp/tests/CMakeLists.txt b/compiler/cpp/tests/CMakeLists.txt index d9c5209134c..6a078ec6304 100644 --- a/compiler/cpp/tests/CMakeLists.txt +++ b/compiler/cpp/tests/CMakeLists.txt @@ -16,7 +16,7 @@ # specific language governing permissions and limitations # under the License. # -cmake_minimum_required(VERSION 2.8.12) +cmake_minimum_required(VERSION 3.16) project(thrift_compiler_tests) diff --git a/compiler/cpp/tests/netcore/t_netcore_generator_helpers_tests.cc b/compiler/cpp/tests/netcore/t_netcore_generator_helpers_tests.cc index 6acedc0f345..348ac9faca9 100644 --- a/compiler/cpp/tests/netcore/t_netcore_generator_helpers_tests.cc +++ b/compiler/cpp/tests/netcore/t_netcore_generator_helpers_tests.cc @@ -5,9 +5,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 @@ -36,7 +36,8 @@ TEST_CASE("t_netstd_generator::netstd_type_usings() without option wcf should re "using System.Threading;\n" "using System.Threading.Tasks;\n" "using Thrift;\n" - "using Thrift.Collections;\n" + endl; + "using Thrift.Collections;\n" + "\n"; t_program* program = new t_program(path, name); t_netstd_generator* gen = new t_netstd_generator(program, parsed_options, option_string); @@ -65,7 +66,8 @@ TEST_CASE("t_netstd_generator::netstd_type_usings() with option wcf should retur "using Thrift;\n" "using Thrift.Collections;\n" "using System.ServiceModel;\n" - "using System.Runtime.Serialization;\n" + endl; + "using System.Runtime.Serialization;\n" + "\n"; t_program* program = new t_program(path, name); t_netstd_generator* gen = new t_netstd_generator(program, parsed_options, option_string); diff --git a/composer.json b/composer.json index 454beeaa9fa..684c1b3875c 100644 --- a/composer.json +++ b/composer.json @@ -18,11 +18,16 @@ "issues": "https://issues.apache.org/jira/browse/THRIFT" }, "require": { - "php": "^5.5 || ^7.0 || ^8.0" + "php": "^7.1 || ^8.0" }, "require-dev": { - "phpunit/phpunit": "~4.8.36", - "squizlabs/php_codesniffer": "3.*" + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "squizlabs/php_codesniffer": "3.*", + "php-mock/php-mock-phpunit": "^2.10", + "ext-json": "*", + "ext-xml": "*", + "ext-curl": "*", + "ext-pcntl": "*" }, "autoload": { "psr-4": {"Thrift\\": "lib/php/lib/"} diff --git a/configure.ac b/configure.ac index a8778237a96..11900184d22 100644 --- a/configure.ac +++ b/configure.ac @@ -20,7 +20,7 @@ AC_PREREQ(2.65) AC_CONFIG_MACRO_DIR([./aclocal]) -AC_INIT([thrift], [0.20.0]) +AC_INIT([thrift], [0.22.0]) AC_CONFIG_AUX_DIR([.]) @@ -214,7 +214,7 @@ if test "$with_kotlin" = "yes"; then AC_PATH_PROG([GRADLE], [gradle]) AC_SUBST(CLASSPATH) AC_SUBST(GRADLE_OPTS) - if test "x$JAVA" != "x" && test "x$JAVAC" != "x" && "x$GRADLE" != "x" ; then + if test "x$JAVA" != "x" && test "x$JAVAC" != "x" && test "x$GRADLE" != "x" ; then have_kotlin="yes" fi fi diff --git a/contrib/Rebus/Properties/AssemblyInfo.cs b/contrib/Rebus/Properties/AssemblyInfo.cs index 33b0aa872c6..25739150526 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.20.0.0")] -[assembly: AssemblyFileVersion("0.20.0.0")] +[assembly: AssemblyVersion("0.22.0.0")] +[assembly: AssemblyFileVersion("0.22.0.0")] diff --git a/contrib/Vagrantfile b/contrib/Vagrantfile index d4a7b82c921..a5371dd82d0 100644 --- a/contrib/Vagrantfile +++ b/contrib/Vagrantfile @@ -46,7 +46,7 @@ sudo apt-get install -qq libboost-dev libboost-test-dev libboost-program-options 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 +sudo apt-get install -qq python-all python-all-dev python-all-dbg python-setuptools python-support # Ruby dependencies sudo apt-get install -qq ruby ruby-dev diff --git a/contrib/fb303/TClientInfo.cpp b/contrib/fb303/TClientInfo.cpp index a4b00cf2d58..c30b42b6122 100644 --- a/contrib/fb303/TClientInfo.cpp +++ b/contrib/fb303/TClientInfo.cpp @@ -149,7 +149,7 @@ void TClientInfoServerHandler::getStatsStrings(vector& result) { char addrBuf[INET6_ADDRSTRLEN]; const char* addrStr = info->getAddr(addrBuf, sizeof addrBuf); if (addrStr == nullptr) { - // cerr << "no addr!" << endl; + // cerr << "no addr!" << '\n'; continue; } @@ -160,7 +160,7 @@ void TClientInfoServerHandler::getStatsStrings(vector& result) { char buf[256]; snprintf(buf, sizeof buf, "%d %s %s %.3f %llu", i, addrStr, callStr, secs, (uint64_t)info->getNCalls()); - + result.push_back(buf); } } diff --git a/contrib/fb303/cpp/ServiceTracker.cpp b/contrib/fb303/cpp/ServiceTracker.cpp index a2e670c768b..43e88474009 100644 --- a/contrib/fb303/cpp/ServiceTracker.cpp +++ b/contrib/fb303/cpp/ServiceTracker.cpp @@ -344,7 +344,7 @@ ServiceTracker::defaultLogMethod(int level, const string &message) break; } cout << '[' << level_string << "] [" << now_pretty << "] " - << message << endl; + << message << '\n'; } } diff --git a/contrib/fb303/py/Makefile.am b/contrib/fb303/py/Makefile.am index 060495e5819..706e10a35e2 100644 --- a/contrib/fb303/py/Makefile.am +++ b/contrib/fb303/py/Makefile.am @@ -18,6 +18,9 @@ # DESTDIR ?= / +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = setup.py src all: diff --git a/contrib/fb303/py/fb303_scripts/fb303_simple_mgmt.py b/contrib/fb303/py/fb303_scripts/fb303_simple_mgmt.py index 5c8f409c1af..62a729e1d8f 100644 --- a/contrib/fb303/py/fb303_scripts/fb303_simple_mgmt.py +++ b/contrib/fb303/py/fb303_scripts/fb303_simple_mgmt.py @@ -19,7 +19,6 @@ # under the License. # -from __future__ import print_function import sys import os from optparse import OptionParser diff --git a/contrib/thrift-maven-plugin/pom.xml b/contrib/thrift-maven-plugin/pom.xml index 46f3cb18327..b314527ae99 100644 --- a/contrib/thrift-maven-plugin/pom.xml +++ b/contrib/thrift-maven-plugin/pom.xml @@ -29,7 +29,7 @@ thrift-maven-plugin maven-plugin thrift-maven-plugin - 0.20.0 + 0.22.0 1.8 diff --git a/contrib/thrift.spec b/contrib/thrift.spec index 90bf4aae567..15e1c5b75a5 100644 --- a/contrib/thrift.spec +++ b/contrib/thrift.spec @@ -28,7 +28,7 @@ Name: thrift License: Apache License v2.0 Group: Development Summary: RPC and serialization framework -Version: 0.20.0 +Version: 0.22.0 Release: 0 URL: http://thrift.apache.org Packager: Thrift Developers diff --git a/contrib/thrift_dump.cpp b/contrib/thrift_dump.cpp index 59c8ac863f5..01864d08383 100644 --- a/contrib/thrift_dump.cpp +++ b/contrib/thrift_dump.cpp @@ -80,12 +80,12 @@ int main(int argc, char *argv[]) { } } } catch (TProtocolException exn) { - cout << "Protocol Exception: " << exn.what() << endl; + cout << "Protocol Exception: " << exn.what() << '\n'; } catch (...) { oprot->getTransport()->flush(); } - cout << endl; + cout << '\n'; return 0; } diff --git a/contrib/zeromq/csharp/AssemblyInfo.cs b/contrib/zeromq/csharp/AssemblyInfo.cs index 8d7ed390b49..27378f30cbf 100644 --- a/contrib/zeromq/csharp/AssemblyInfo.cs +++ b/contrib/zeromq/csharp/AssemblyInfo.cs @@ -36,7 +36,7 @@ // The form "{Major}.{Minor}.*" will automatically update the build and revision, // and "{Major}.{Minor}.{Build}.*" will update just the revision. -[assembly: AssemblyVersion("0.20.0.0")] +[assembly: AssemblyVersion("0.22.0.0")] // The following attributes are used to specify the signing key for the assembly, // if desired. See the Mono documentation for more information about signing. diff --git a/contrib/zeromq/test-client.cpp b/contrib/zeromq/test-client.cpp index 159c25030d5..f2bd2133ed8 100644 --- a/contrib/zeromq/test-client.cpp +++ b/contrib/zeromq/test-client.cpp @@ -33,7 +33,7 @@ int main(int argc, char** argv) { usleep(50000); } else { int value = client.get(); - std::cout << value << std::endl; + std::cout << value << '\n'; } return 0; diff --git a/debian/changelog b/debian/changelog index 147c4b4bf65..df7e6931f3d 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +thrift (0.21.0) stable; urgency=low + + * update to 0.21.0 + + -- Apache Thrift Developers Mon, 02 Sep 2024 23:30:00 +0100 + thrift (0.20.0) stable; urgency=low * update to 0.20.0 diff --git a/debian/control b/debian/control index 1b41991c3ec..06c0d483416 100644 --- a/debian/control +++ b/debian/control @@ -32,7 +32,7 @@ Description: Compiler for Thrift definition files Package: python-thrift Architecture: any Section: python -Depends: ${python:Depends}, ${shlibs:Depends}, ${misc:Depends}, python-six +Depends: ${python:Depends}, ${shlibs:Depends}, ${misc:Depends} Recommends: python-twisted-web, python-backports.ssl-match-hostname, python-ipaddress Provides: ${python:Provides} Description: Python bindings for Thrift (Python 2) @@ -65,7 +65,7 @@ Description: Python bindings for Thrift (debug version) Package: python3-thrift Architecture: any Section: python -Depends: ${python3:Depends}, ${shlibs:Depends}, ${misc:Depends}, python3-six +Depends: ${python3:Depends}, ${shlibs:Depends}, ${misc:Depends} Recommends: python3-twisted-web Provides: ${python:Provides} Description: Python bindings for Thrift (Python 3) diff --git a/debian/copyright b/debian/copyright index e39dc742c51..7245167c173 100644 --- a/debian/copyright +++ b/debian/copyright @@ -72,9 +72,12 @@ under the Apache 2.0 License: lib/netstd/Thrift/Transport/TTransport.cs lib/netstd/Thrift/Transport/TTransportException.cs lib/netstd/Thrift/Transport/TTransportFactory.cs - lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Properties/AssemblyInfo.cs - lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift.PublicInterfaces.Compile.Tests.csproj - lib/rb/lib/thrift.rb + lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.netstd2/Properties/AssemblyInfo.cs + lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.netstd2/Thrift.Compile.netstd2.csproj + lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.net8/Properties/AssemblyInfo.cs + lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.net8/Thrift.Compile.net8.csproj + lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.net9/Properties/AssemblyInfo.cs + lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.net9/Thrift.Compile.net9.csproj lib/st/README.md lib/st/thrift.st lib/cpp/test/OptionalRequiredTest.cpp diff --git a/doap.rdf b/doap.rdf index 703082acb81..f36508ef0f1 100644 --- a/doap.rdf +++ b/doap.rdf @@ -55,6 +55,11 @@ + + Apache Thrift + 2024-09-02 + 0.21.0 + Apache Thrift 2024-02-04 diff --git a/doc/ReleaseManagement.md b/doc/ReleaseManagement.md index e06c9b4468e..4077d61667a 100644 --- a/doc/ReleaseManagement.md +++ b/doc/ReleaseManagement.md @@ -70,9 +70,9 @@ All Apache Thrift releases go through a 72-hour final release candidate voting p 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 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,resolved)%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. + 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,resolved)%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. @@ -126,12 +126,12 @@ All Apache Thrift releases go through a 72-hour final release candidate voting p 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: + For example, if the row above was row "1" in EXCEL it would look something like: ```text - =CONCAT("[", B1, "]", + =CONCAT("[", A1, "]", "https://issues.apache.org/jira/browse/", - B1, " - ", B3) + A1, " - ", C1) ``` 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. @@ -148,12 +148,16 @@ All Apache Thrift releases go through a 72-hour final release candidate voting p ~$ 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 + 1. In the clean copy of the release branch, build the container image: + + ```bash + ~$ docker build -t thrift build/docker/ubuntu-jammy + ``` + + 1. Run the container and `make dist`: + + ```bash + ~$ docker run -v $(pwd):/thrift/src -it thrift /bin/bash root@8b4101188aa2:/thrift/src# ./bootstrap.sh && ./configure && make dist ``` @@ -275,9 +279,10 @@ All Apache Thrift releases go through a 72-hour final release candidate voting p 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. + I start this voting thread with my own +1 vote. + This vote will close in 72 hours on 2019-07-06 21:00 UTC [ ] +1 Release this as Apache Thrift 1.0.0 diff --git a/doc/install/README.md b/doc/install/README.md index d073e918dcf..0ebe77c7110 100644 --- a/doc/install/README.md +++ b/doc/install/README.md @@ -32,7 +32,7 @@ These are only required if you choose to build the libraries for the given langu * Gradle 8.4 * C#: Mono 1.2.4 (and pkg-config to detect it) or Visual Studio 2005+ * Python 2.6 (including header files for extension modules) -* PHP 5.0 (optionally including header files for extension modules) +* PHP 7.1 (optionally including header files for extension modules) * Ruby 1.8 * bundler gem * Erlang R12 (R11 works but not recommended) diff --git a/doc/specs/idl.md b/doc/specs/idl.md index 0980f5bbc6d..9777af4e0c9 100644 --- a/doc/specs/idl.md +++ b/doc/specs/idl.md @@ -1,6 +1,6 @@ ## Thrift interface description language -For Thrift version 0.20.0. +For Thrift version 0.22.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. diff --git a/doc/specs/thrift-compact-protocol.md b/doc/specs/thrift-compact-protocol.md index a31a2d329c0..3e1c4b4548f 100644 --- a/doc/specs/thrift-compact-protocol.md +++ b/doc/specs/thrift-compact-protocol.md @@ -48,43 +48,38 @@ For background on Thrift see the [Thrift whitepaper (pdf)](https://thrift.apache ### Integer encoding -The _compact protocol_ uses multiple encodings for ints: the _zigzag int_, and the _var int_. +The _compact protocol_ uses [ZigZag](https://en.wikipedia.org/wiki/Variable-length_quantity#Zigzag_encoding)'ed +varint (aka [ULEB128](https://en.wikipedia.org/wiki/LEB128)) encoding. -Values of type `int32` and `int64` are first transformed to a *zigzag int*. A zigzag int folds positive and negative -numbers into the positive number space. When we read 0, 1, 2, 3, 4 or 5 from the wire, this is translated to 0, -1, 1, --2 or 2 respectively. Here are the (Scala) formulas to convert from int32/int64 to a zigzag int and back: +Values of type `int8` are encoded as one byte, rest are converted to `int64`, Zigzag'ed then encoded as varint. +Zigzag encoding maps signed integers to another domain, one where the sign bit is encoded in the least significant +bit (LSB). For example 0 maps to 0, -1 to 1, 1 to 2, -2 to 3, etc. Hence the term zigzag. Mapping the sign bit to +the LSB is important for compactness when the absolute value of the value is small, as ULEB encoding is more +efficient for small values. Here are the (Scala) formulas to convert from `int64` to a zigzag `int64` and back: ```scala -def intToZigZag(n: Int): Int = (n << 1) ^ (n >> 31) -def zigzagToInt(n: Int): Int = (n >>> 1) ^ - (n & 1) -def longToZigZag(n: Long): Long = (n << 1) ^ (n >> 63) -def zigzagToLong(n: Long): Long = (n >>> 1) ^ - (n & 1) +def ToZigzag(n: Long): Long = (n << 1) ^ (n >> 63) +def FromZigzag(n: Long): Long = (n >>> 1) ^ - (n & 1) ``` -The zigzag int is then encoded as a *var int*, also known as *Unsigned LEB128*. Var ints take 1 to 5 bytes (int32) or -1 to 10 bytes (int64). The process consists in taking a Big Endian unsigned integer, left-padding the bit-string to -make it a multiple of 7 bits, splitting it into 7-bit groups, prefixing the most-significant 7-bit group with the 0 -bit, prefixing the remaining 7-bit groups with the 1 bit and encoding the resulting bit-string in Little Endian. +A ULEB128 is encoded 7-bits at a time, starting from the LSB. Each 7-bits are encoded as 8-bits with the top bit set +if this is not the last byte, unset otherwise. For example, the integer 50399 is encoded as follows: ``` -50399 = 1100 0100 1101 1111 (Big Endian representation) - = 00000 1100 0100 1101 1111 (Left-padding) - = 0000011 0001001 1011111 (7-bit groups) - = 00000011 10001001 11011111 (Most-significant bit prefixes) - = 11011111 10001001 00000011 (Little Endian representation) - = 0xDF 0x89 0x03 +50399 = 11000100 11011111 (LSB) + = 0000011 0001001 1011111 (7-bit groups) + = 00000011 10001001 11011111 (add continuation bits) + = 0x03 0x89 0xDF (hex) +→ 0xDF 0x89 0x03 (write to ram LSB first) ``` -Var ints are sometimes used directly inside the compact protocol to represent positive numbers. - -To encode an `int16` as zigzag int, it is first converted to an `int32` and then encoded as such. The type `int8` simply -uses a single byte as in the binary protocol. +Varints are sometimes used directly inside the compact protocol to represent positive numbers. ### Enum encoding -The generated code encodes `Enum`s by taking the ordinal value and then encoding that as an int32. +The generated code encodes `Enum`s by taking the ordinal value and then encoding that as an `int32`. ### Binary encoding @@ -99,36 +94,33 @@ Binary protocol, binary data, 1+ bytes: Where: -* `byte length` is the length of the byte array, using var int encoding (must be >= 0). +* `byte length` is the length of the byte array, using varint encoding (must be >= 0). * `bytes` are the bytes of the byte array. ### String encoding -*String*s are first encoded to UTF-8, and then send as binary. They do not -include a NUL delimiter. +*String*s are first encoded to UTF-8, and then send as binary. They do not include a NUL delimiter. ### Double encoding -Values of type `double` are first converted to an int64 according to the IEEE 754 floating-point "double format" bit -layout. Most run-times provide a library to make this conversion. But while the binary protocol encodes the int64 -in 8 bytes in big endian order, the compact protocol encodes it in little endian order - this is due to an early -implementation bug that finally became the de-facto standard. +Values of type `double` are first converted to an `int64` according to the IEEE 754 floating-point "double format" +bit layout. Most run-times provide a library to make this conversion. But while the binary protocol encodes the +`int64` in 8 bytes in big endian order, the compact protocol encodes it in little endian order - this is due to an +early implementation bug that finally became the de-facto standard. ### Boolean encoding Booleans are encoded differently depending on whether it is a field value (in a struct) or an element value (in a set, -list or map). Field values are encoded directly in the field header. Element values of type `bool` are sent as an int8; -true as `1` and false as `0`. +list or map). Field values are encoded directly in the field header. Element values of type `bool` are sent as an +`int8`; true as `1` and false as `2`. ### Universal unique identifier encoding -Values of `uuid` type are expected as 16-byte binary in big endian (or "network") order. Byte order conversion -might be necessary on certain platforms, e.g. Windows holds GUIDs in a complex record-like structure whose -memory layout differs. +Values of `uuid` type are expected as 16-byte binary in big endian order. Byte order conversion might be necessary on +certain platforms, e.g. Windows holds GUIDs in a complex record-like structure whose memory layout differs. *Note*: Since the length is fixed, no `byte length` prefix is necessary and the field is always 16 bytes long. - ## Message A `Message` on the wire looks as follows: @@ -145,8 +137,8 @@ Where: * `pppppppp` is the protocol id, fixed to `1000 0010`, 0x82. * `mmm` is the message type, an unsigned 3 bit integer. * `vvvvv` is the version, an unsigned 5 bit integer, fixed to `00001`. -* `seq id` is the sequence id, a signed 32 bit integer encoded as a var int. -* `name length` is the byte length of the name field, a signed 32 bit integer encoded as a var int (must be >= 0). +* `seq id` is the sequence id, a signed 32 bit integer encoded as a varint. +* `name length` is the byte length of the name field, a signed 32 bit integer encoded as a varint (must be >= 0). * `name` is the method name to invoke, a UTF-8 encoded string. Message types are encoded with the following values: @@ -204,7 +196,7 @@ Where: * `dddd` is the field id delta, an unsigned 4 bits integer, strictly positive. * `tttt` is field-type id, an unsigned 4 bit integer. -* `field id` the field id, a signed 16 bit integer encoded as zigzag int. +* `field id` the field id, a varint (int16). Max field id is 32767. * `field-value` the encoded field value. The field id delta can be computed by `current-field-id - previous-field-id`, or just `current-field-id` if this is the @@ -250,14 +242,14 @@ Where: * `ssss` is the size, 4 bit unsigned int, values `0` - `14` * `tttt` is the element-type, a 4 bit unsigned int -* `size` is the size, a var int (int32), positive values `15` or higher +* `size` is the size, a varint (int32), positive values `15` or higher * `elements` are the encoded elements The short form should be used when the length is in the range 0 - 14 (inclusive). -The following element-types are used (see note below): +The following element-types are used (see note 1 below): -* `BOOL`, encoded as `2` +* `BOOL`, encoded as `1` or `2` (see note 2 below) * `I8`, encoded as `3` * `I16`, encoded as `4` * `I32`, encoded as `5` @@ -270,8 +262,12 @@ The following element-types are used (see note below): * `STRUCT`, used for structs and union fields, encoded as `12` * `UUID`, encoded as `13` -*Note*: Although field-types and element-types lists are currently very similar, there is _no guarantee_ that this will +*Note*: +1. Although field-types and element-types lists are currently very similar, there is _no guarantee_ that this will remain true after new types are added. +2. For historical and compatibility reasons, a reader should be capable to deal with *both* cases. +The only valid value in the original spec was `2`, but due to an widespread implementation bug the defacto +standard across large parts of the library became `1` instead. As a result, both values are now allowed. The maximum list/set size is configurable. By default there is no limit (meaning the limit is the maximum int32 value: 2147483647). diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 00000000000..2f70a8824f0 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,50 @@ +import globals from "globals"; +import js from "@eslint/js"; +import eslintPluginPrettierRecommended from "eslint-plugin-prettier/recommended"; + +export default [ + { + ignores: [ + // TODO: Use eslint on js lib and generated code + + // Ignore lib/js for now, which uses jshint currently + "lib/js/*", + // Ignore all generated code for now + "**/gen-*/", + + // Don't lint nested node_modules + "**/node_modules/", + ], + }, + js.configs.recommended, + eslintPluginPrettierRecommended, + { + languageOptions: { + globals: { + ...globals.node, + }, + + ecmaVersion: 2022, + sourceType: "commonjs", + }, + + rules: { + "no-console": "off", + "no-var": "error", + "prefer-const": "error", + + "no-constant-condition": [ + "error", + { + checkLoops: false, + }, + ], + }, + }, + { + files: ["**/*.mjs"], + languageOptions: { + sourceType: "module", + }, + }, +]; diff --git a/go.mod b/go.mod index b435d78a368..01690d887d4 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,3 @@ module github.com/apache/thrift -go 1.21 +go 1.23 diff --git a/lib/Makefile.am b/lib/Makefile.am index 79888e42d62..e277911c41c 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -103,6 +103,9 @@ endif # All of the libs that don't use Automake need to go in here # so they will end up in our release tarballs. +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ d \ dart \ diff --git a/lib/c_glib/Makefile.am b/lib/c_glib/Makefile.am index b2061bbc789..80a51650a31 100644 --- a/lib/c_glib/Makefile.am +++ b/lib/c_glib/Makefile.am @@ -112,6 +112,9 @@ include_processor_HEADERS = src/thrift/c_glib/processor/thrift_processor.h \ src/thrift/c_glib/processor/thrift_multiplexed_processor.h +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ CMakeLists.txt \ coding_standards.md \ diff --git a/lib/c_glib/test/CMakeLists.txt b/lib/c_glib/test/CMakeLists.txt index 4d3092fb8a1..4f60473b25c 100644 --- a/lib/c_glib/test/CMakeLists.txt +++ b/lib/c_glib/test/CMakeLists.txt @@ -231,7 +231,7 @@ add_custom_command(OUTPUT gen-cpp/ThriftTest.h gen-cpp/ThriftTest_constants.h gen-cpp/ThriftTest_types.h - COMMAND ${THRIFT_COMPILER} --gen cpp ${PROJECT_SOURCE_DIR}/test/v0.16/ThriftTest.thrift + COMMAND ${THRIFT_COMPILER} --gen cpp ${PROJECT_SOURCE_DIR}/test/ThriftTest.thrift ) # TODO: Add memory checks using ctest_memcheck or similar diff --git a/lib/c_glib/test/Makefile.am b/lib/c_glib/test/Makefile.am index f3a0c30df67..0a5f220ac91 100644 --- a/lib/c_glib/test/Makefile.am +++ b/lib/c_glib/test/Makefile.am @@ -335,7 +335,7 @@ gen-c_glib/t_test_optional_required_test_types.c gen-c_glib/t_test_optional_requ gen-c_glib/t_test_second_service.c gen-c_glib/t_test_thrift_test.c gen-c_glib/t_test_thrift_test_types.c gen-c_glib/t_test_second_service.h gen-c_glib/t_test_thrift_test.h gen-c_glib/t_test_thrift_test_types.h: ../../../test/v0.16/ThriftTest.thrift $(THRIFT) $(THRIFT) --gen c_glib $< -gen-cpp/ThriftTest.cpp gen-cpp/ThriftTest_constants.cpp gen-cpp/ThriftTest_types.cpp: ../../../test/v0.16/ThriftTest.thrift $(THRIFT) +gen-cpp/ThriftTest.cpp gen-cpp/ThriftTest_constants.cpp gen-cpp/ThriftTest_types.cpp: ../../../test/ThriftTest.thrift $(THRIFT) $(THRIFT) --gen cpp $< TESTS = \ @@ -401,6 +401,9 @@ CLEANFILES = \ *.gcda \ *.gcov +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ CMakeLists.txt \ ContainerTest.thrift diff --git a/lib/c_glib/test/testthrifttestclient.cpp b/lib/c_glib/test/testthrifttestclient.cpp index 77daf3d37fa..745feb786c0 100644 --- a/lib/c_glib/test/testthrifttestclient.cpp +++ b/lib/c_glib/test/testthrifttestclient.cpp @@ -51,7 +51,6 @@ using namespace apache::thrift::transport; using namespace thrift::test; using std::cout; -using std::endl; using std::fixed; using std::make_pair; using std::map; @@ -76,51 +75,56 @@ class TestHandler : public ThriftTestIf { TestHandler() = default; void testVoid() override { - cout << "[C -> C++] testVoid()" << endl; + cout << "[C -> C++] testVoid()" << '\n'; } void testString(string& out, const string &thing) override { - cout << "[C -> C++] testString(\"" << thing << "\")" << endl; + cout << "[C -> C++] testString(\"" << thing << "\")" << '\n'; out = thing; } bool testBool(const bool thing) override { - cout << "[C -> C++] testBool(" << (thing ? "true" : "false") << ")" << endl; + cout << "[C -> C++] testBool(" << (thing ? "true" : "false") << ")" << '\n'; return thing; } int8_t testByte(const int8_t thing) override { - cout << "[C -> C++] testByte(" << (int)thing << ")" << endl; + cout << "[C -> C++] testByte(" << (int)thing << ")" << '\n'; return thing; } int32_t testI32(const int32_t thing) override { - cout << "[C -> C++] testI32(" << thing << ")" << endl; + cout << "[C -> C++] testI32(" << thing << ")" << '\n'; return thing; } int64_t testI64(const int64_t thing) override { - cout << "[C -> C++] testI64(" << thing << ")" << endl; + cout << "[C -> C++] testI64(" << thing << ")" << '\n'; return thing; } double testDouble(const double thing) override { cout.precision(6); - cout << "[C -> C++] testDouble(" << fixed << thing << ")" << endl; + cout << "[C -> C++] testDouble(" << fixed << thing << ")" << '\n'; return thing; } void testBinary(string& out, const string &thing) override { - cout << "[C -> C++] testBinary(\"" << thing << "\")" << endl; + cout << "[C -> C++] testBinary(\"" << thing << "\")" << '\n'; + out = thing; + } + + void testUuid(apache::thrift::TUuid& out, const apache::thrift::TUuid& thing) override { + cout << "[C -> C++] testUuid(\"" << thing << "\")" << '\n'; out = 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; + cout << "[C -> C++] testStruct({\"" << thing.string_thing << "\", " << (int)thing.byte_thing << ", " << thing.i32_thing << ", " << thing.i64_thing << "})" << '\n'; out = thing; } 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; + cout << "[C -> C++] testNest({" << (int)nest.byte_thing << ", {\"" << thing.string_thing << "\", " << (int)thing.byte_thing << ", " << thing.i32_thing << ", " << thing.i64_thing << "}, " << nest.i32_thing << "})" << '\n'; out = nest; } @@ -136,7 +140,7 @@ class TestHandler : public ThriftTestIf { } cout << m_iter->first << " => " << m_iter->second; } - cout << "})" << endl; + cout << "})" << '\n'; out = thing; } @@ -152,7 +156,7 @@ class TestHandler : public ThriftTestIf { } cout << "\"" << m_iter->first << "\" => \"" << m_iter->second << "\""; } - cout << "})" << endl; + cout << "})" << '\n'; out = thing; } @@ -169,7 +173,7 @@ class TestHandler : public ThriftTestIf { } cout << *s_iter; } - cout << "})" << endl; + cout << "})" << '\n'; out = thing; } @@ -185,21 +189,21 @@ class TestHandler : public ThriftTestIf { } cout << *l_iter; } - cout << "})" << endl; + cout << "})" << '\n'; out = thing; } Numberz::type testEnum(const Numberz::type thing) override { - cout << "[C -> C++] testEnum(" << thing << ")" << endl; + cout << "[C -> C++] testEnum(" << thing << ")" << '\n'; return thing; } UserId testTypedef(const UserId thing) override { - cout << "[C -> C++] testTypedef(" << thing << ")" << endl; + cout << "[C -> C++] testTypedef(" << thing << ")" << '\n'; return thing; } void testMapMap(map > &mapmap, const int32_t hello) override { - cout << "[C -> C++] testMapMap(" << hello << ")" << endl; + cout << "[C -> C++] testMapMap(" << hello << ")" << '\n'; map pos; map neg; @@ -216,7 +220,7 @@ class TestHandler : public ThriftTestIf { void testInsanity(map > &insane, const Insanity &argument) override { THRIFT_UNUSED_VARIABLE (argument); - cout << "[C -> C++] testInsanity()" << endl; + cout << "[C -> C++] testInsanity()" << '\n'; Xtruct hello; hello.string_thing = "Hello2"; @@ -278,7 +282,7 @@ class TestHandler : public ThriftTestIf { } cout << "}, "; } - cout << "}" << endl; + cout << "}" << '\n'; } @@ -288,7 +292,7 @@ class TestHandler : public ThriftTestIf { THRIFT_UNUSED_VARIABLE (arg4); THRIFT_UNUSED_VARIABLE (arg5); - cout << "[C -> C++] testMulti()" << endl; + cout << "[C -> C++] testMulti()" << '\n'; hello.string_thing = "Hello2"; hello.byte_thing = arg0; @@ -299,7 +303,7 @@ class TestHandler : public ThriftTestIf { void testException(const std::string &arg) noexcept(false) override { - cout << "[C -> C++] testException(" << arg << ")" << endl; + cout << "[C -> C++] testException(" << arg << ")" << '\n'; if (arg.compare("Xception") == 0) { Xception e; e.errorCode = 1001; @@ -317,7 +321,7 @@ class TestHandler : public ThriftTestIf { void testMultiException(Xtruct &result, const std::string &arg0, const std::string &arg1) noexcept(false) override { - cout << "[C -> C++] testMultiException(" << arg0 << ", " << arg1 << ")" << endl; + cout << "[C -> C++] testMultiException(" << arg0 << ", " << arg1 << ")" << '\n'; if (arg0.compare("Xception") == 0) { Xception e; @@ -336,9 +340,9 @@ class TestHandler : public ThriftTestIf { } void testOneway(int sleepFor) override { - cout << "testOneway(" << sleepFor << "): Sleeping..." << endl; + cout << "testOneway(" << sleepFor << "): Sleeping..." << '\n'; sleep(sleepFor); - cout << "testOneway(" << sleepFor << "): done sleeping!" << endl; + cout << "testOneway(" << sleepFor << "): done sleeping!" << '\n'; } }; diff --git a/lib/c_glib/test/testthrifttestzlibclient.cpp b/lib/c_glib/test/testthrifttestzlibclient.cpp index 5c4b931570d..783d06550a2 100644 --- a/lib/c_glib/test/testthrifttestzlibclient.cpp +++ b/lib/c_glib/test/testthrifttestzlibclient.cpp @@ -46,7 +46,6 @@ using namespace apache::thrift::transport; using namespace thrift::test; using std::cout; -using std::endl; using std::fixed; using std::make_pair; using std::map; @@ -71,51 +70,56 @@ class TestHandler : public ThriftTestIf { TestHandler() = default; void testVoid() override { - cout << "[C -> C++] testVoid()" << endl; + cout << "[C -> C++] testVoid()" << '\n'; } void testString(string& out, const string &thing) override { - cout << "[C -> C++] testString(\"" << thing << "\")" << endl; + cout << "[C -> C++] testString(\"" << thing << "\")" << '\n'; out = thing; } bool testBool(const bool thing) override { - cout << "[C -> C++] testBool(" << (thing ? "true" : "false") << ")" << endl; + cout << "[C -> C++] testBool(" << (thing ? "true" : "false") << ")" << '\n'; return thing; } int8_t testByte(const int8_t thing) override { - cout << "[C -> C++] testByte(" << (int)thing << ")" << endl; + cout << "[C -> C++] testByte(" << (int)thing << ")" << '\n'; return thing; } int32_t testI32(const int32_t thing) override { - cout << "[C -> C++] testI32(" << thing << ")" << endl; + cout << "[C -> C++] testI32(" << thing << ")" << '\n'; return thing; } int64_t testI64(const int64_t thing) override { - cout << "[C -> C++] testI64(" << thing << ")" << endl; + cout << "[C -> C++] testI64(" << thing << ")" << '\n'; return thing; } double testDouble(const double thing) override { cout.precision(6); - cout << "[C -> C++] testDouble(" << fixed << thing << ")" << endl; + cout << "[C -> C++] testDouble(" << fixed << thing << ")" << '\n'; return thing; } void testBinary(string& out, const string &thing) override { - cout << "[C -> C++] testBinary(\"" << thing << "\")" << endl; + cout << "[C -> C++] testBinary(\"" << thing << "\")" << '\n'; + out = thing; + } + + void testUuid(apache::thrift::TUuid& out, const apache::thrift::TUuid& thing) override { + cout << "[C -> C++] testUuid(\"" << thing << "\")" << '\n'; out = 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; + cout << "[C -> C++] testStruct({\"" << thing.string_thing << "\", " << (int)thing.byte_thing << ", " << thing.i32_thing << ", " << thing.i64_thing << "})" << '\n'; out = thing; } 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; + cout << "[C -> C++] testNest({" << (int)nest.byte_thing << ", {\"" << thing.string_thing << "\", " << (int)thing.byte_thing << ", " << thing.i32_thing << ", " << thing.i64_thing << "}, " << nest.i32_thing << "})" << '\n'; out = nest; } @@ -131,7 +135,7 @@ class TestHandler : public ThriftTestIf { } cout << m_iter->first << " => " << m_iter->second; } - cout << "})" << endl; + cout << "})" << '\n'; out = thing; } @@ -147,7 +151,7 @@ class TestHandler : public ThriftTestIf { } cout << "\"" << m_iter->first << "\" => \"" << m_iter->second << "\""; } - cout << "})" << endl; + cout << "})" << '\n'; out = thing; } @@ -164,7 +168,7 @@ class TestHandler : public ThriftTestIf { } cout << *s_iter; } - cout << "})" << endl; + cout << "})" << '\n'; out = thing; } @@ -180,21 +184,22 @@ class TestHandler : public ThriftTestIf { } cout << *l_iter; } - cout << "})" << endl; + cout << "})" << '\n'; out = thing; } Numberz::type testEnum(const Numberz::type thing) override { - cout << "[C -> C++] testEnum(" << thing << ")" << endl; + cout << "[C -> C++] testEnum(" << thing << ")" << '\n'; return thing; } UserId testTypedef(const UserId thing) override { - cout << "[C -> C++] testTypedef(" << thing << ")" << endl; - return thing; } + cout << "[C -> C++] testTypedef(" << thing << ")" << '\n'; + return thing; + } void testMapMap(map > &mapmap, const int32_t hello) override { - cout << "[C -> C++] testMapMap(" << hello << ")" << endl; + cout << "[C -> C++] testMapMap(" << hello << ")" << '\n'; map pos; map neg; @@ -211,7 +216,7 @@ class TestHandler : public ThriftTestIf { void testInsanity(map > &insane, const Insanity &argument) override { THRIFT_UNUSED_VARIABLE (argument); - cout << "[C -> C++] testInsanity()" << endl; + cout << "[C -> C++] testInsanity()" << '\n'; Xtruct hello; hello.string_thing = "Hello2"; @@ -273,7 +278,7 @@ class TestHandler : public ThriftTestIf { } cout << "}, "; } - cout << "}" << endl; + cout << "}" << '\n'; } @@ -283,7 +288,7 @@ class TestHandler : public ThriftTestIf { THRIFT_UNUSED_VARIABLE (arg4); THRIFT_UNUSED_VARIABLE (arg5); - cout << "[C -> C++] testMulti()" << endl; + cout << "[C -> C++] testMulti()" << '\n'; hello.string_thing = "Hello2"; hello.byte_thing = arg0; @@ -292,9 +297,9 @@ class TestHandler : public ThriftTestIf { } void testException(const std::string &arg) - throw(Xception, apache::thrift::TException) override + noexcept(false) override { - cout << "[C -> C++] testException(" << arg << ")" << endl; + cout << "[C -> C++] testException(" << arg << ")" << '\n'; if (arg.compare("Xception") == 0) { Xception e; e.errorCode = 1001; @@ -310,9 +315,9 @@ class TestHandler : public ThriftTestIf { } } - void testMultiException(Xtruct &result, const std::string &arg0, const std::string &arg1) throw(Xception, Xception2) override { + void testMultiException(Xtruct &result, const std::string &arg0, const std::string &arg1) noexcept(false) override { - cout << "[C -> C++] testMultiException(" << arg0 << ", " << arg1 << ")" << endl; + cout << "[C -> C++] testMultiException(" << arg0 << ", " << arg1 << ")" << '\n'; if (arg0.compare("Xception") == 0) { Xception e; @@ -331,9 +336,9 @@ class TestHandler : public ThriftTestIf { } void testOneway(int sleepFor) override { - cout << "testOneway(" << sleepFor << "): Sleeping..." << endl; + cout << "testOneway(" << sleepFor << "): Sleeping..." << '\n'; sleep(sleepFor); - cout << "testOneway(" << sleepFor << "): done sleeping!" << endl; + cout << "testOneway(" << sleepFor << "): done sleeping!" << '\n'; } }; diff --git a/lib/cl/Makefile.am b/lib/cl/Makefile.am index 34b38861d23..a54eb922eb4 100644 --- a/lib/cl/Makefile.am +++ b/lib/cl/Makefile.am @@ -32,6 +32,9 @@ clean-local: $(RM) run-tests quicklisp.lisp backport-update.zip $(RM) -rf lib externals quicklisp +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ README.md \ READMES \ diff --git a/lib/cpp/CMakeLists.txt b/lib/cpp/CMakeLists.txt index 6a66e5ad1a7..5980734f380 100644 --- a/lib/cpp/CMakeLists.txt +++ b/lib/cpp/CMakeLists.txt @@ -31,6 +31,7 @@ endif() set(thriftcpp_SOURCES src/thrift/TApplicationException.cpp src/thrift/TOutput.cpp + src/thrift/TUuid.cpp src/thrift/async/TAsyncChannel.cpp src/thrift/async/TAsyncProtocolProcessor.cpp src/thrift/async/TConcurrentClientSyncInfo.h diff --git a/lib/cpp/Makefile.am b/lib/cpp/Makefile.am index c015b0db60f..3d7beab68ae 100644 --- a/lib/cpp/Makefile.am +++ b/lib/cpp/Makefile.am @@ -57,6 +57,7 @@ AM_CPPFLAGS = $(BOOST_CPPFLAGS) $(OPENSSL_INCLUDES) -I$(srcdir)/src -D__STDC_FOR libthrift_la_SOURCES = src/thrift/TApplicationException.cpp \ src/thrift/TOutput.cpp \ + src/thrift/TUuid.cpp \ src/thrift/VirtualProfiling.cpp \ src/thrift/async/TAsyncChannel.cpp \ src/thrift/async/TAsyncProtocolProcessor.cpp \ @@ -136,6 +137,7 @@ include_thrift_HEADERS = \ src/thrift/thrift-config.h \ src/thrift/thrift_export.h \ src/thrift/TDispatchProcessor.h \ + src/thrift/TUuid.h \ src/thrift/Thrift.h \ src/thrift/TOutput.h \ src/thrift/TProcessor.h \ @@ -252,6 +254,9 @@ WINDOWS_DIST = \ libthriftnb.vcxproj.filters \ 3rdparty.props +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ CMakeLists.txt \ coding_standards.md \ diff --git a/lib/cpp/README.md b/lib/cpp/README.md index 8074484f197..74983aeb1ff 100644 --- a/lib/cpp/README.md +++ b/lib/cpp/README.md @@ -232,6 +232,32 @@ OpenSSL's RAND_poll() when OpenSSL library is first initialized. The PRNG seed is key to the application security. This method should be overridden if it's not strong enough for you. +# Thrift UUID + +The `uuid` `BaseType` is implemented in C++ by the `apache::thrift::TUuid` class. This class +is a strong wrapper class around an internal buffer of 16 bytes. + +The `apache::thrift::TUuid` supports construction from different UUID string representations. +Some examples of supported string formats are: + +* `"hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh"` +* `"{hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh}"` +* `"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh"` +* `"{hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh}"` + +## `TUuid` and `boost::uuids::uuid` + +Internally the TUuid class is implemented using the `boost::uuids::uuid` library. As a result the TUuid +can seamlessly interoperate with the boost UUID type since the underlying data structure is the same. + +For convenience, when boost is already used by a project the `THRIFT_TUUID_SUPPORT_BOOST_UUID` preprocessor +directive can be set when including the thrift library to enable construction of a `TUuid` from a +`boost::uuids::uuid`. By default this is an implicit constructor that can be changed to be explicit +by defining the `THRIFT_TUUID_BOOST_CONSTRUCTOR_EXPLICIT` preprocessor directive. + +The thrift library does not need to be compiled differently when this constructor is needed. The preprocessor +directives can be set on the project that uses the thrift library. + # Deprecations ## 0.12.0 diff --git a/lib/cpp/libthrift.vcxproj b/lib/cpp/libthrift.vcxproj index 0b5e16de7c4..7fcccfe99ee 100644 --- a/lib/cpp/libthrift.vcxproj +++ b/lib/cpp/libthrift.vcxproj @@ -57,6 +57,7 @@ + @@ -96,6 +97,7 @@ + diff --git a/lib/cpp/libthrift.vcxproj.filters b/lib/cpp/libthrift.vcxproj.filters index 98426fac85b..4b2ba3b2782 100644 --- a/lib/cpp/libthrift.vcxproj.filters +++ b/lib/cpp/libthrift.vcxproj.filters @@ -4,6 +4,7 @@ transport + @@ -106,6 +107,7 @@ protocol + diff --git a/lib/cpp/src/thrift/TNonCopyable.h b/lib/cpp/src/thrift/TNonCopyable.h index a60f1f0fb4b..51c94e2a0d5 100644 --- a/lib/cpp/src/thrift/TNonCopyable.h +++ b/lib/cpp/src/thrift/TNonCopyable.h @@ -30,7 +30,7 @@ namespace thrift { class TNonCopyable { protected: TNonCopyable() = default; - ~TNonCopyable() = default; + virtual ~TNonCopyable() = default; TNonCopyable(const TNonCopyable&) = delete; TNonCopyable& operator=(const TNonCopyable&) = delete; diff --git a/lib/cpp/src/thrift/TOutput.cpp b/lib/cpp/src/thrift/TOutput.cpp index 971e5dbf7b1..72360afebff 100644 --- a/lib/cpp/src/thrift/TOutput.cpp +++ b/lib/cpp/src/thrift/TOutput.cpp @@ -31,7 +31,7 @@ namespace apache { namespace thrift { -THRIFT_EXPORT TOutput GlobalOutput; +/*THRIFT_EXPORT*/ TOutput GlobalOutput; // if you need this exported, build your own wrapper lib around and export it yourself TOutput::TOutput() : f_(&errorTimeWrapper) {} diff --git a/lib/cpp/src/thrift/TOutput.h b/lib/cpp/src/thrift/TOutput.h index 26c9a563aed..8a9061a1985 100644 --- a/lib/cpp/src/thrift/TOutput.h +++ b/lib/cpp/src/thrift/TOutput.h @@ -20,7 +20,7 @@ #ifndef _THRIFT_OUTPUT_H_ #define _THRIFT_OUTPUT_H_ 1 -#include +//#include namespace apache { namespace thrift { @@ -53,7 +53,7 @@ class TOutput { void (*f_)(const char*); }; -THRIFT_EXPORT extern TOutput GlobalOutput; +/*THRIFT_EXPORT*/ extern TOutput GlobalOutput; // if you need this exported, build your own wrapper lib around and export it yourself } } // namespace apache::thrift diff --git a/lib/cpp/src/thrift/TToString.h b/lib/cpp/src/thrift/TToString.h index d91c58c4b2e..fe460326918 100644 --- a/lib/cpp/src/thrift/TToString.h +++ b/lib/cpp/src/thrift/TToString.h @@ -45,6 +45,14 @@ std::string to_string(const T& t) { return o.str(); } +// special handling of i8 datatypes (THRIFT-5272) +inline std::string to_string(const int8_t& t) { + std::ostringstream o; + o.imbue(default_locale); + o << static_cast(t); + return o.str(); +} + // TODO: replace the computations below with std::numeric_limits::max_digits10 once C++11 // is enabled. inline std::string to_string(const float& t) { diff --git a/lib/cpp/src/thrift/TUuid.cpp b/lib/cpp/src/thrift/TUuid.cpp new file mode 100644 index 00000000000..062b286d8b5 --- /dev/null +++ b/lib/cpp/src/thrift/TUuid.cpp @@ -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. + */ + +#include + +#include +#include +#include + +namespace apache { +namespace thrift { + +namespace { +static const boost::uuids::string_generator gen; +} + +TUuid::TUuid(const std::string& str) noexcept { + std::fill(this->begin(), this->end(), 0); + if (str.empty()) { + return ; + } + + try { + const boost::uuids::uuid uuid = gen(str); + std::copy(uuid.begin(), uuid.end(), this->begin()); + } catch (const std::runtime_error&) { + // Invalid string most probably + } +} + +bool TUuid::is_nil() const noexcept { + boost::uuids::uuid uuid_tmp{}; + std::copy(this->begin(), this->end(), std::begin(uuid_tmp)); + return uuid_tmp.is_nil(); +} + +std::string to_string(const TUuid& in) { + boost::uuids::uuid uuid_tmp{}; + std::copy(std::begin(in), std::end(in), std::begin(uuid_tmp)); + return boost::uuids::to_string(uuid_tmp); +} + + +} +} // apache::thrift \ No newline at end of file diff --git a/lib/cpp/src/thrift/TUuid.h b/lib/cpp/src/thrift/TUuid.h new file mode 100644 index 00000000000..405772aedc5 --- /dev/null +++ b/lib/cpp/src/thrift/TUuid.h @@ -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. + */ + +#ifndef _THRIFT_TUUID_H_ +#define _THRIFT_TUUID_H_ 1 + +#include + +#ifdef THRIFT_TUUID_SUPPORT_BOOST_UUID +#include +#endif // THRIFT_TUUID_SUPPORT_BOOST_UUID + +#include +#include + +namespace apache { +namespace thrift { + +/** + * Thrift wrapper class for a UUID type. + * + * The UUID is stored as a 16 byte buffer. + * This class stores the UUID in network order when assigned from a string. + */ +class TUuid { +public: + typedef uint8_t value_type; + typedef uint8_t* iterator; + typedef uint8_t const* const_iterator; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + + TUuid() = default; + TUuid(const TUuid& other) = default; + TUuid(TUuid&& other) = default; + TUuid& operator=(const TUuid&) = default; + TUuid& operator=(TUuid&&) = default; + ~TUuid() = default; + + /** + * Construct the object from a 16 byte buffer. + */ + explicit TUuid(const uint8_t (&data)[16]) noexcept + { + std::copy(std::begin(data), std::end(data), std::begin(this->data_)); + } + + /** + * Construct the object from the specified string. + * + * Supported string formats are: + * - "hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh" + * - "{hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh}" + * - "hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh" + * - "{hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh}" + * + * If the string is invalid, the object will be set to a + * nil (empty) UUID. + */ + explicit TUuid(const std::string& str) noexcept; + +#ifdef THRIFT_TUUID_SUPPORT_BOOST_UUID + /** + * Construct the TUuid from a boost::uuids::uuid. + * + * This constructor will only be available if the THRIFT_TUUID_SUPPORT_BOOST_UUID + * compiler directive is set when this file is included. + * + * This constructor is by default implicit. It can be made explicit by defining the + * THRIFT_TUUID_BOOST_CONSTRUCTOR_EXPLICIT compiler directive. + */ + #ifdef THRIFT_TUUID_BOOST_CONSTRUCTOR_EXPLICIT + explicit + #endif // THRIFT_TUUID_BOOST_CONSTRUCTOR_EXPLICIT + TUuid(const boost::uuids::uuid& buuid) noexcept + { + std::copy(buuid.begin(), buuid.end(), std::begin(this->data_)); + } +#endif // THRIFT_TUUID_SUPPORT_BOOST_UUID + + /** + * Check if the UUID is nil. + */ + bool is_nil() const noexcept; + + /** + * Compare two TUuid objects for equality. + */ + inline bool operator==(const TUuid& other) const; + + /** + * Compare two TUuid objects for inequality. + */ + inline bool operator!=(const TUuid& other) const; + + iterator begin() noexcept { return data_; } + const_iterator begin() const noexcept { return data_; } + iterator end() noexcept { return data_ + size(); } + const_iterator end() const noexcept { return data_ + size(); } + size_type size() const noexcept { return 16; } + inline const_iterator data() const { return data_; } + inline iterator data() { return data_; } + + void swap(TUuid& other) noexcept { std::swap(data_, other.data_); } + +private: + /** + * The UUID data. + */ + uint8_t data_[16] = {}; +}; + +/** + * Get the String representation of a TUUID. + * + * The format returned is: + * - "hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh" + */ +std::string to_string(const TUuid& uuid) noexcept(false); + +/** + * Swap two TUuid objects + */ +inline void swap(TUuid& lhs, TUuid& rhs) noexcept { + lhs.swap(rhs); +} + +/** + * TUuid equality comparison operator implementation + */ +inline bool TUuid::operator==(const TUuid& other) const { + // Compare using temporary strings. + // Can't use strcmp() since we expect embeded zeros + // Perhaps the reason we should use std::array instead + return std::string(this->begin(), this->end()) == std::string(other.begin(), other.end()); +} + +/** + * TUuid inequality comparison operator implementation + */ +inline bool TUuid::operator!=(const TUuid& other) const { + return !(*this == other); +} + +/** + * TUuid ostream stream operator implementation + */ +inline std::ostream& operator<<(std::ostream& out, const TUuid& obj) { + out << to_string(obj); + return out; +} + +} // namespace thrift +} // namespace apache + +#endif // #ifndef _THRIFT_TUUID_H_ diff --git a/lib/cpp/src/thrift/Thrift.h b/lib/cpp/src/thrift/Thrift.h index d5066ee7107..338694b7f3f 100644 --- a/lib/cpp/src/thrift/Thrift.h +++ b/lib/cpp/src/thrift/Thrift.h @@ -58,12 +58,14 @@ class TEnumIterator int operator++() { return ++ii_; } - bool operator!=(const TEnumIterator& end) { - THRIFT_UNUSED_VARIABLE(end); - assert(end.n_ == -1); - return (ii_ != n_); + bool operator==(const TEnumIterator& rhs) const { + bool is_end = ii_ == n_ || n_ == -1; + bool is_rhs_end = rhs.ii_ == rhs.n_ || rhs.n_ == -1; + return (ii_ == rhs.ii_ && n_ == rhs.n_) || (is_end && is_rhs_end); } + bool operator!=(const TEnumIterator& rhs) const { return !(*this == rhs); } + std::pair operator*() const { return std::make_pair(enums_[ii_], names_[ii_]); } private: diff --git a/lib/cpp/src/thrift/async/TConcurrentClientSyncInfo.h b/lib/cpp/src/thrift/async/TConcurrentClientSyncInfo.h index 0bc5eb565f5..dd9b055e87e 100644 --- a/lib/cpp/src/thrift/async/TConcurrentClientSyncInfo.h +++ b/lib/cpp/src/thrift/async/TConcurrentClientSyncInfo.h @@ -36,7 +36,7 @@ class TConcurrentClientSyncInfo; class TConcurrentSendSentry { public: explicit TConcurrentSendSentry(TConcurrentClientSyncInfo* sync); - ~TConcurrentSendSentry(); + virtual ~TConcurrentSendSentry(); void commit(); @@ -48,7 +48,7 @@ class TConcurrentSendSentry { class TConcurrentRecvSentry { public: TConcurrentRecvSentry(TConcurrentClientSyncInfo* sync, int32_t seqid); - ~TConcurrentRecvSentry(); + virtual ~TConcurrentRecvSentry(); void commit(); diff --git a/lib/cpp/src/thrift/async/TEvhttpClientChannel.cpp b/lib/cpp/src/thrift/async/TEvhttpClientChannel.cpp index 7656596859a..43d4034f618 100644 --- a/lib/cpp/src/thrift/async/TEvhttpClientChannel.cpp +++ b/lib/cpp/src/thrift/async/TEvhttpClientChannel.cpp @@ -147,8 +147,7 @@ void TEvhttpClientChannel::finish(struct evhttp_request* req) { self->finish(req); } catch (std::exception& e) { // don't propagate a C++ exception in C code (e.g. libevent) - std::cerr << "TEvhttpClientChannel::response exception thrown (ignored): " << e.what() - << std::endl; + std::cerr << "TEvhttpClientChannel::response exception thrown (ignored): " << e.what() << '\n'; } } } diff --git a/lib/cpp/src/thrift/async/TEvhttpServer.cpp b/lib/cpp/src/thrift/async/TEvhttpServer.cpp index 7d2cf21c0fc..bea9001500d 100644 --- a/lib/cpp/src/thrift/async/TEvhttpServer.cpp +++ b/lib/cpp/src/thrift/async/TEvhttpServer.cpp @@ -127,13 +127,13 @@ void TEvhttpServer::complete(RequestContext* ctx, bool success) { int rv = evhttp_add_header(ctx->req->output_headers, "Content-Type", "application/x-thrift"); if (rv != 0) { // TODO: Log an error. - std::cerr << "evhttp_add_header failed " << __FILE__ << ":" << __LINE__ << std::endl; + std::cerr << "evhttp_add_header failed " << __FILE__ << ":" << __LINE__ << '\n'; } struct evbuffer* buf = evbuffer_new(); if (buf == nullptr) { // TODO: Log an error. - std::cerr << "evbuffer_new failed " << __FILE__ << ":" << __LINE__ << std::endl; + std::cerr << "evbuffer_new failed " << __FILE__ << ":" << __LINE__ << '\n'; } else { uint8_t* obuf; uint32_t sz; @@ -141,8 +141,7 @@ void TEvhttpServer::complete(RequestContext* ctx, bool success) { int ret = evbuffer_add(buf, obuf, sz); if (ret != 0) { // TODO: Log an error. - std::cerr << "evhttp_add failed with " << ret << " " << __FILE__ << ":" << __LINE__ - << std::endl; + std::cerr << "evhttp_add failed with " << ret << " " << __FILE__ << ":" << __LINE__ << '\n'; } } diff --git a/lib/cpp/src/thrift/async/TEvhttpServer.h b/lib/cpp/src/thrift/async/TEvhttpServer.h index c5bf3b6eef4..aecfadef2fb 100644 --- a/lib/cpp/src/thrift/async/TEvhttpServer.h +++ b/lib/cpp/src/thrift/async/TEvhttpServer.h @@ -50,7 +50,7 @@ class TEvhttpServer { */ TEvhttpServer(std::shared_ptr processor, int port); - ~TEvhttpServer(); + virtual ~TEvhttpServer(); static void request(struct evhttp_request* req, void* self); int serve(); diff --git a/lib/cpp/src/thrift/concurrency/Mutex.h b/lib/cpp/src/thrift/concurrency/Mutex.h index 1e5c3fba37c..12f1729d6bf 100644 --- a/lib/cpp/src/thrift/concurrency/Mutex.h +++ b/lib/cpp/src/thrift/concurrency/Mutex.h @@ -20,6 +20,7 @@ #ifndef _THRIFT_CONCURRENCY_MUTEX_H_ #define _THRIFT_CONCURRENCY_MUTEX_H_ 1 +#include #include #include diff --git a/lib/cpp/src/thrift/protocol/TBinaryProtocol.h b/lib/cpp/src/thrift/protocol/TBinaryProtocol.h index 7b829c76833..cba6e69485d 100644 --- a/lib/cpp/src/thrift/protocol/TBinaryProtocol.h +++ b/lib/cpp/src/thrift/protocol/TBinaryProtocol.h @@ -119,6 +119,8 @@ class TBinaryProtocolT : public TVirtualProtocol::writeBinary(const std::string return TBinaryProtocolT::writeString(str); } +template +uint32_t TBinaryProtocolT::writeUUID(const TUuid& uuid) { + // TODO: Consider endian swapping, see lib/delphi/src/Thrift.Utils.pas:377 + this->trans_->write(uuid.data(), uuid.size()); + return 16; +} + /** * Reading functions */ @@ -286,7 +293,7 @@ uint32_t TBinaryProtocolT::readMapBegin(TType& keyType, throw TProtocolException(TProtocolException::SIZE_LIMIT); } size = (uint32_t)sizei; - + TMap map(keyType, valType, size); checkReadBytesAvailable(map); @@ -428,6 +435,12 @@ uint32_t TBinaryProtocolT::readBinary(std::string& str) return TBinaryProtocolT::readString(str); } +template +uint32_t TBinaryProtocolT::readUUID(TUuid& uuid) { + this->trans_->readAll(uuid.begin(), uuid.size()); + return 16; +} + template template uint32_t TBinaryProtocolT::readStringBody(StrType& str, int32_t size) { @@ -480,6 +493,7 @@ int TBinaryProtocolT::getMinSerializedSize(TType type) case T_MAP: return sizeof(int); // element count case T_SET: return sizeof(int); // element count case T_LIST: return sizeof(int); // element count + case T_UUID: return 16; // 16 bytes default: throw TProtocolException(TProtocolException::UNKNOWN, "unrecognized type code"); } } diff --git a/lib/cpp/src/thrift/protocol/TCompactProtocol.h b/lib/cpp/src/thrift/protocol/TCompactProtocol.h index 792a2d89e3b..c7d81eea6e5 100644 --- a/lib/cpp/src/thrift/protocol/TCompactProtocol.h +++ b/lib/cpp/src/thrift/protocol/TCompactProtocol.h @@ -35,12 +35,12 @@ namespace protocol { template class TCompactProtocolT : public TVirtualProtocol > { public: - static const int8_t PROTOCOL_ID = (int8_t)0x82u; + static const int8_t PROTOCOL_ID = static_cast(0x82u); static const int8_t VERSION_N = 1; static const int8_t VERSION_MASK = 0x1f; // 0001 1111 protected: - static const int8_t TYPE_MASK = (int8_t)0xE0u; // 1110 0000 + static const int8_t TYPE_MASK = static_cast(0xE0u); // 1110 0000 static const int8_t TYPE_BITS = 0x07; // 0000 0111 static const int32_t TYPE_SHIFT_AMOUNT = 5; @@ -140,6 +140,8 @@ class TCompactProtocolT : public TVirtualProtocol uint32_t writeBinary(const std::string& str); + uint32_t writeUUID(const TUuid& str); + int getMinSerializedSize(TType type) override; void checkReadBytesAvailable(TSet& set) override @@ -213,6 +215,8 @@ class TCompactProtocolT : public TVirtualProtocol uint32_t readBinary(std::string& str); + uint32_t readUUID(TUuid& str); + /* *These methods are here for the struct to call, but don't have any wire * encoding. diff --git a/lib/cpp/src/thrift/protocol/TCompactProtocol.tcc b/lib/cpp/src/thrift/protocol/TCompactProtocol.tcc index 9270ab89902..b57568f8dcb 100644 --- a/lib/cpp/src/thrift/protocol/TCompactProtocol.tcc +++ b/lib/cpp/src/thrift/protocol/TCompactProtocol.tcc @@ -61,10 +61,11 @@ enum Types { CT_LIST = 0x09, CT_SET = 0x0A, CT_MAP = 0x0B, - CT_STRUCT = 0x0C + CT_STRUCT = 0x0C, + CT_UUID = 0x0D }; -const int8_t TTypeToCType[16] = { +const int8_t TTypeToCType[17] = { CT_STOP, // T_STOP 0, // unused CT_BOOLEAN_TRUE, // T_BOOL @@ -81,6 +82,7 @@ const int8_t TTypeToCType[16] = { CT_MAP, // T_MAP CT_SET, // T_SET CT_LIST, // T_LIST + CT_UUID, // T_UUID }; }} // end detail::compact namespace @@ -93,7 +95,7 @@ uint32_t TCompactProtocolT::writeMessageBegin( const int32_t seqid) { uint32_t wsize = 0; wsize += writeByte(PROTOCOL_ID); - wsize += writeByte((VERSION_N & VERSION_MASK) | (((int32_t)messageType << TYPE_SHIFT_AMOUNT) & TYPE_MASK)); + wsize += writeByte((VERSION_N & VERSION_MASK) | ((static_cast(messageType) << TYPE_SHIFT_AMOUNT) & TYPE_MASK)); wsize += writeVarint32(seqid); wsize += writeString(name); return wsize; @@ -221,7 +223,7 @@ uint32_t TCompactProtocolT::writeBool(const bool value) { template uint32_t TCompactProtocolT::writeByte(const int8_t byte) { - trans_->write((uint8_t*)&byte, 1); + trans_->write(reinterpret_cast(&byte), 1); return 1; } @@ -259,7 +261,7 @@ uint32_t TCompactProtocolT::writeDouble(const double dub) { auto bits = bitwise_cast(dub); bits = THRIFT_htolell(bits); - trans_->write((uint8_t*)&bits, 8); + trans_->write(reinterpret_cast(&bits), 8); return 8; } @@ -282,10 +284,19 @@ uint32_t TCompactProtocolT::writeBinary(const std::string& str) { if(ssize > (std::numeric_limits::max)() - wsize) throw TProtocolException(TProtocolException::SIZE_LIMIT); wsize += ssize; - trans_->write((uint8_t*)str.data(), ssize); + trans_->write(reinterpret_cast(str.data()), ssize); return wsize; } +/** + * Write a TUuid to the wire + */ +template +uint32_t TCompactProtocolT::writeUUID(const TUuid& uuid) { + trans_->write(uuid.data(), uuid.size()); + return uuid.size(); +} + // // Internal Writing methods // @@ -350,10 +361,10 @@ uint32_t TCompactProtocolT::writeVarint32(uint32_t n) { while (true) { if ((n & ~0x7F) == 0) { - buf[wsize++] = (int8_t)n; + buf[wsize++] = static_cast(n); break; } else { - buf[wsize++] = (int8_t)((n & 0x7F) | 0x80); + buf[wsize++] = static_cast((n & 0x7F) | 0x80); n >>= 7; } } @@ -371,10 +382,10 @@ uint32_t TCompactProtocolT::writeVarint64(uint64_t n) { while (true) { if ((n & ~0x7FL) == 0) { - buf[wsize++] = (int8_t)n; + buf[wsize++] = static_cast(n); break; } else { - buf[wsize++] = (int8_t)((n & 0x7F) | 0x80); + buf[wsize++] = static_cast((n & 0x7F) | 0x80); n >>= 7; } } @@ -431,12 +442,12 @@ uint32_t TCompactProtocolT::readMessageBegin( } rsize += readByte(versionAndType); - version = (int8_t)(versionAndType & VERSION_MASK); + version = static_cast(versionAndType & VERSION_MASK); if (version != VERSION_N) { throw TProtocolException(TProtocolException::BAD_VERSION, "Bad protocol version"); } - messageType = (TMessageType)((versionAndType >> TYPE_SHIFT_AMOUNT) & TYPE_BITS); + messageType = static_cast((versionAndType >> TYPE_SHIFT_AMOUNT) & TYPE_BITS); rsize += readVarint32(seqid); rsize += readString(name); @@ -489,12 +500,12 @@ uint32_t TCompactProtocolT::readFieldBegin(std::string& name, } // mask off the 4 MSB of the type header. it could contain a field id delta. - auto modifier = (int16_t)(((uint8_t)byte & 0xf0) >> 4); + auto modifier = static_cast(static_cast(byte & 0xf0) >> 4); if (modifier == 0) { // not a delta, look ahead for the zigzag varint field id. rsize += readI16(fieldId); } else { - fieldId = (int16_t)(lastFieldId_ + modifier); + fieldId = static_cast(lastFieldId_ + modifier); } fieldType = getTType(type); @@ -535,9 +546,9 @@ uint32_t TCompactProtocolT::readMapBegin(TType& keyType, throw TProtocolException(TProtocolException::SIZE_LIMIT); } - keyType = getTType((int8_t)((uint8_t)kvType >> 4)); - valType = getTType((int8_t)((uint8_t)kvType & 0xf)); - size = (uint32_t)msize; + keyType = getTType(static_cast(static_cast(kvType) >> 4)); + valType = getTType(static_cast(static_cast(kvType) & 0xf)); + size = static_cast(msize); TMap map(keyType, valType, size); checkReadBytesAvailable(map); @@ -560,7 +571,7 @@ uint32_t TCompactProtocolT::readListBegin(TType& elemType, rsize += readByte(size_and_type); - lsize = ((uint8_t)size_and_type >> 4) & 0x0f; + lsize = (static_cast(size_and_type) >> 4) & 0x0f; if (lsize == 15) { rsize += readVarint32(lsize); } @@ -571,8 +582,8 @@ uint32_t TCompactProtocolT::readListBegin(TType& elemType, throw TProtocolException(TProtocolException::SIZE_LIMIT); } - elemType = getTType((int8_t)(size_and_type & 0x0f)); - size = (uint32_t)lsize; + elemType = getTType(static_cast(size_and_type & 0x0f)); + size = static_cast(lsize); TList list(elemType, size); checkReadBytesAvailable(list); @@ -618,7 +629,7 @@ template uint32_t TCompactProtocolT::readByte(int8_t& byte) { uint8_t b[1]; trans_->readAll(b, 1); - byte = *(int8_t*)b; + byte = static_cast(b[0]); return 1; } @@ -629,7 +640,7 @@ template uint32_t TCompactProtocolT::readI16(int16_t& i16) { int32_t value; uint32_t rsize = readVarint32(value); - i16 = (int16_t)zigzagToI32(value); + i16 = static_cast(zigzagToI32(value)); return rsize; } @@ -701,21 +712,31 @@ uint32_t TCompactProtocolT::readBinary(std::string& str) { throw TProtocolException(TProtocolException::SIZE_LIMIT); } + // Check against MaxMessageSize before alloc + trans_->checkReadBytesAvailable(static_cast(size)); + // Use the heap here to prevent stack overflow for v. large strings if (size > string_buf_size_ || string_buf_ == nullptr) { - void* new_string_buf = std::realloc(string_buf_, (uint32_t)size); + void* new_string_buf = std::realloc(string_buf_, static_cast(size)); if (new_string_buf == nullptr) { throw std::bad_alloc(); } - string_buf_ = (uint8_t*)new_string_buf; + string_buf_ = static_cast(new_string_buf); string_buf_size_ = size; } trans_->readAll(string_buf_, size); - str.assign((char*)string_buf_, size); + str.assign(reinterpret_cast(string_buf_), size); + + return rsize + static_cast(size); +} - trans_->checkReadBytesAvailable(rsize + (uint32_t)size); - return rsize + (uint32_t)size; +/** + * Read a TUuid from the wire. + */ +template +uint32_t TCompactProtocolT::readUUID(TUuid& uuid) { + return trans_->readAll(uuid.begin(), uuid.size()); } /** @@ -726,7 +747,7 @@ template uint32_t TCompactProtocolT::readVarint32(int32_t& i32) { int64_t val; uint32_t rsize = readVarint64(val); - i32 = (int32_t)val; + i32 = static_cast(val); return rsize; } @@ -748,7 +769,7 @@ uint32_t TCompactProtocolT::readVarint64(int64_t& i64) { while (true) { uint8_t byte = borrowed[rsize]; rsize++; - val |= (uint64_t)(byte & 0x7f) << shift; + val |= static_cast(byte & 0x7f) << shift; shift += 7; if (!(byte & 0x80)) { i64 = val; @@ -767,7 +788,7 @@ uint32_t TCompactProtocolT::readVarint64(int64_t& i64) { while (true) { uint8_t byte; rsize += trans_->readAll(&byte, 1); - val |= (uint64_t)(byte & 0x7f) << shift; + val |= static_cast(byte & 0x7f) << shift; shift += 7; if (!(byte & 0x80)) { i64 = val; @@ -825,8 +846,10 @@ TType TCompactProtocolT::getTType(int8_t type) { return T_MAP; case detail::compact::CT_STRUCT: return T_STRUCT; + case detail::compact::CT_UUID: + return T_UUID; default: - throw TException(std::string("don't know what type: ") + (char)type); + throw TException(std::string("don't know what type: ") + static_cast(type)); } } @@ -849,6 +872,7 @@ int TCompactProtocolT::getMinSerializedSize(TType type) case T_MAP: return sizeof(int8_t); // element count case T_SET: return sizeof(int8_t); // element count case T_LIST: return sizeof(int8_t); // element count + case T_UUID: return 16; // 16 bytes default: throw TProtocolException(TProtocolException::UNKNOWN, "unrecognized type code"); } } diff --git a/lib/cpp/src/thrift/protocol/TDebugProtocol.cpp b/lib/cpp/src/thrift/protocol/TDebugProtocol.cpp index 0e6d4a2aac3..6e88313db64 100644 --- a/lib/cpp/src/thrift/protocol/TDebugProtocol.cpp +++ b/lib/cpp/src/thrift/protocol/TDebugProtocol.cpp @@ -70,10 +70,8 @@ string TDebugProtocol::fieldTypeName(TType type) { return "set"; case T_LIST: return "list"; - case T_UTF8: - return "utf8"; - case T_UTF16: - return "utf16"; + case T_UUID: + return "uuid"; default: return "unknown"; } @@ -388,6 +386,17 @@ uint32_t TDebugProtocol::writeBinary(const string& str) { // XXX Hex? return TDebugProtocol::writeString(str); } + +uint32_t TDebugProtocol::writeUUID(const TUuid& uuid) { + size_t size = writePlain("{\n"); + indentUp(); + size += writeIndented("[raw] = "); + size += writeString(std::string(std::begin(uuid), std::end(uuid))); + size += writeIndented("[enc] = \"" + to_string(uuid) + "\"\n"); + indentDown(); + size += writeIndented("}\n"); + return size; +} } } } // apache::thrift::protocol diff --git a/lib/cpp/src/thrift/protocol/TDebugProtocol.h b/lib/cpp/src/thrift/protocol/TDebugProtocol.h index 41bb0d4ec94..02662f1ab15 100644 --- a/lib/cpp/src/thrift/protocol/TDebugProtocol.h +++ b/lib/cpp/src/thrift/protocol/TDebugProtocol.h @@ -110,6 +110,8 @@ class TDebugProtocol : public TVirtualProtocol { uint32_t writeBinary(const std::string& str); + uint32_t writeUUID(const TUuid& uuid); + private: void indentUp(); void indentDown(); diff --git a/lib/cpp/src/thrift/protocol/TEnum.h b/lib/cpp/src/thrift/protocol/TEnum.h index 9636785e327..bbd1247dc19 100644 --- a/lib/cpp/src/thrift/protocol/TEnum.h +++ b/lib/cpp/src/thrift/protocol/TEnum.h @@ -18,7 +18,7 @@ */ #ifndef _THRIFT_ENUM_H_ -#define _THRIFT_ENUM_H_ +#define _THRIFT_ENUM_H_ namespace apache { namespace thrift { @@ -46,8 +46,7 @@ enum TType { T_MAP = 13, T_SET = 14, T_LIST = 15, - T_UTF8 = 16, - T_UTF16 = 17 + T_UUID = 16, }; /** @@ -63,4 +62,4 @@ enum TMessageType { }}} // apache::thrift::protocol -#endif // #define _THRIFT_ENUM_H_ +#endif // #define _THRIFT_ENUM_H_ diff --git a/lib/cpp/src/thrift/protocol/TJSONProtocol.cpp b/lib/cpp/src/thrift/protocol/TJSONProtocol.cpp index 6e4e8ef0db6..3805869a936 100644 --- a/lib/cpp/src/thrift/protocol/TJSONProtocol.cpp +++ b/lib/cpp/src/thrift/protocol/TJSONProtocol.cpp @@ -68,6 +68,7 @@ static const std::string kTypeNameString("str"); static const std::string kTypeNameMap("map"); static const std::string kTypeNameList("lst"); static const std::string kTypeNameSet("set"); +static const std::string kTypeNameUuid("uid"); static const std::string& getTypeNameForTypeID(TType typeID) { switch (typeID) { @@ -93,6 +94,8 @@ static const std::string& getTypeNameForTypeID(TType typeID) { return kTypeNameSet; case T_LIST: return kTypeNameList; + case T_UUID: + return kTypeNameUuid; default: throw TProtocolException(TProtocolException::NOT_IMPLEMENTED, "Unrecognized type"); } @@ -140,6 +143,9 @@ static TType getTypeIDForTypeName(const std::string& name) { case 't': result = T_BOOL; break; + case 'u': + result = T_UUID; + break; } } if (result == T_STOP) { @@ -710,6 +716,10 @@ uint32_t TJSONProtocol::writeBinary(const std::string& str) { return writeJSONBase64(str); } +uint32_t TJSONProtocol::writeUUID(const TUuid& uuid) { + return writeJSONString(to_string(uuid)); +} + /** * Reading functions */ @@ -1106,6 +1116,13 @@ uint32_t TJSONProtocol::readBinary(std::string& str) { return readJSONBase64(str); } +uint32_t TJSONProtocol::readUUID(TUuid& uuid) { + std::string uuid_str; + const uint32_t result = readJSONString(uuid_str); + uuid = TUuid{uuid_str}; + return result; +} + // Return the minimum number of bytes a type will consume on the wire int TJSONProtocol::getMinSerializedSize(TType type) { @@ -1113,7 +1130,7 @@ int TJSONProtocol::getMinSerializedSize(TType type) { case T_STOP: return 0; case T_VOID: return 0; - case T_BOOL: return 1; // written as int + case T_BOOL: return 1; // written as int case T_BYTE: return 1; case T_DOUBLE: return 1; case T_I16: return 1; @@ -1124,6 +1141,7 @@ int TJSONProtocol::getMinSerializedSize(TType type) case T_MAP: return 2; // empty map case T_SET: return 2; // empty set case T_LIST: return 2; // empty list + case T_UUID: return 16; // empty UUID default: throw TProtocolException(TProtocolException::UNKNOWN, "unrecognized type code"); } } diff --git a/lib/cpp/src/thrift/protocol/TJSONProtocol.h b/lib/cpp/src/thrift/protocol/TJSONProtocol.h index d01bdf80141..09eb6eab1bf 100644 --- a/lib/cpp/src/thrift/protocol/TJSONProtocol.h +++ b/lib/cpp/src/thrift/protocol/TJSONProtocol.h @@ -198,6 +198,8 @@ class TJSONProtocol : public TVirtualProtocol { uint32_t writeBinary(const std::string& str); + uint32_t writeUUID(const TUuid& uuid); + /** * Reading functions */ @@ -245,6 +247,8 @@ class TJSONProtocol : public TVirtualProtocol { uint32_t readBinary(std::string& str); + uint32_t readUUID(TUuid& uuid); + int getMinSerializedSize(TType type) override; void checkReadBytesAvailable(TSet& set) override diff --git a/lib/cpp/src/thrift/protocol/TProtocol.h b/lib/cpp/src/thrift/protocol/TProtocol.h index 237c1e56883..37b0db71199 100644 --- a/lib/cpp/src/thrift/protocol/TProtocol.h +++ b/lib/cpp/src/thrift/protocol/TProtocol.h @@ -49,6 +49,7 @@ #include #include #include +#include #include @@ -169,8 +170,8 @@ static inline To bitwise_cast(From from) { | (((n) & 0x0000ff00ul) << 8) \ | (((n) & 0x000000fful) << 24) ) # define bswap_16(n) \ - ( (((n) & ((unsigned short)0xff00ul)) >> 8) \ - | (((n) & ((unsigned short)0x00fful)) << 8) ) + ( (((n) & (static_cast(0xff00ul)) >> 8) \ + | (((n) & (static_cast(0x00fful)) << 8) ) # define THRIFT_htolell(n) bswap_64(n) # define THRIFT_letohll(n) bswap_64(n) # define THRIFT_htolel(n) bswap_32(n) @@ -190,11 +191,11 @@ static inline To bitwise_cast(From from) { # define THRIFT_ntohll(n) bswap_64(n) # define THRIFT_htonll(n) bswap_64(n) # elif defined(_MSC_VER) /* Microsoft Visual C++ */ -# define THRIFT_ntohll(n) ( _byteswap_uint64((uint64_t)n) ) -# define THRIFT_htonll(n) ( _byteswap_uint64((uint64_t)n) ) +# define THRIFT_ntohll(n) ( _byteswap_uint64(static_cast(n)) ) +# define THRIFT_htonll(n) ( _byteswap_uint64(static_cast(n)) ) # elif !defined(THRIFT_ntohll) /* Not GNUC/GLIBC or MSVC */ -# define THRIFT_ntohll(n) ( (((uint64_t)ntohl((uint32_t)n)) << 32) + ntohl((uint32_t)(n >> 32)) ) -# define THRIFT_htonll(n) ( (((uint64_t)htonl((uint32_t)n)) << 32) + htonl((uint32_t)(n >> 32)) ) +# define THRIFT_ntohll(n) ( (static_cast(ntohl(static_cast(n))) << 32) + ntohl(static_cast(n >> 32)) ) +# define THRIFT_htonll(n) ( (static_cast(htonl(static_cast(n))) << 32) + htonl(static_cast(n >> 32)) ) # endif /* GNUC/GLIBC or MSVC or something else */ #else /* __THRIFT_BYTE_ORDER */ # error "Can't define THRIFT_htonll or THRIFT_ntohll!" @@ -275,6 +276,8 @@ class TProtocol { virtual uint32_t writeBinary_virt(const std::string& str) = 0; + virtual uint32_t writeUUID_virt(const TUuid& uuid) = 0; + uint32_t writeMessageBegin(const std::string& name, const TMessageType messageType, const int32_t seqid) { @@ -382,6 +385,11 @@ class TProtocol { return writeBinary_virt(str); } + uint32_t writeUUID(const TUuid& uuid) { + T_VIRTUAL_CALL(); + return writeUUID_virt(uuid); + } + /** * Reading functions */ @@ -430,6 +438,8 @@ class TProtocol { virtual uint32_t readBinary_virt(std::string& str) = 0; + virtual uint32_t readUUID_virt(TUuid& uuid) = 0; + uint32_t readMessageBegin(std::string& name, TMessageType& messageType, int32_t& seqid) { T_VIRTUAL_CALL(); return readMessageBegin_virt(name, messageType, seqid); @@ -530,6 +540,11 @@ class TProtocol { return readBinary_virt(str); } + uint32_t readUUID(TUuid& uuid) { + T_VIRTUAL_CALL(); + return readUUID_virt(uuid); + } + /* * std::vector is specialized for bool, and its elements are individual bits * rather than bools. We need to define a different version of readBool() diff --git a/lib/cpp/src/thrift/protocol/TProtocolDecorator.h b/lib/cpp/src/thrift/protocol/TProtocolDecorator.h index 5258159f149..88fbbdeb1c2 100644 --- a/lib/cpp/src/thrift/protocol/TProtocolDecorator.h +++ b/lib/cpp/src/thrift/protocol/TProtocolDecorator.h @@ -92,6 +92,7 @@ class TProtocolDecorator : public TProtocol { 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); } + uint32_t writeUUID_virt(const TUuid& uuid) override { return protocol->writeUUID(uuid); } uint32_t readMessageBegin_virt(std::string& name, TMessageType& messageType, @@ -140,6 +141,7 @@ class TProtocolDecorator : public TProtocol { uint32_t readString_virt(std::string& str) override { return protocol->readString(str); } uint32_t readBinary_virt(std::string& str) override { return protocol->readBinary(str); } + uint32_t readUUID_virt(TUuid& uuid) override { return protocol->readUUID(uuid); } private: shared_ptr protocol; diff --git a/lib/cpp/src/thrift/protocol/TVirtualProtocol.h b/lib/cpp/src/thrift/protocol/TVirtualProtocol.h index b7fe929af20..8789e473c73 100644 --- a/lib/cpp/src/thrift/protocol/TVirtualProtocol.h +++ b/lib/cpp/src/thrift/protocol/TVirtualProtocol.h @@ -393,6 +393,10 @@ class TVirtualProtocol : public Super_ { return static_cast(this)->writeBinary(str); } + uint32_t writeUUID_virt(const TUuid& uuid) override { + return static_cast(this)->writeUUID(uuid); + } + /** * Reading functions */ @@ -471,6 +475,10 @@ class TVirtualProtocol : public Super_ { return static_cast(this)->readBinary(str); } + uint32_t readUUID_virt(TUuid& uuid) override { + return static_cast(this)->readUUID(uuid); + } + uint32_t skip_virt(TType type) override { return static_cast(this)->skip(type); } /* diff --git a/lib/cpp/src/thrift/server/TNonblockingServer.cpp b/lib/cpp/src/thrift/server/TNonblockingServer.cpp index ae92da3afbf..d53535bdadc 100644 --- a/lib/cpp/src/thrift/server/TNonblockingServer.cpp +++ b/lib/cpp/src/thrift/server/TNonblockingServer.cpp @@ -886,8 +886,8 @@ void TNonblockingServer::TConnection::checkIdleBufferMemLimit(size_t readLimit, TNonblockingServer::~TNonblockingServer() { // Close any active connections (moves them to the idle connection stack) - while (activeConnections_.size()) { - activeConnections_.front()->close(); + while (!activeConnections_.empty()) { + (*activeConnections_.begin())->close(); } // Clean up unused TConnection objects in connectionStack_ while (!connectionStack_.empty()) { @@ -931,7 +931,8 @@ TNonblockingServer::TConnection* TNonblockingServer::createConnection(std::share result->setSocket(socket); result->init(ioThread); } - activeConnections_.push_back(result); + + activeConnections_.insert(result); return result; } @@ -941,11 +942,7 @@ TNonblockingServer::TConnection* TNonblockingServer::createConnection(std::share void TNonblockingServer::returnConnection(TConnection* connection) { Guard g(connMutex_); - activeConnections_.erase(std::remove(activeConnections_.begin(), - activeConnections_.end(), - connection), - activeConnections_.end()); - + activeConnections_.erase(connection); if (connectionStackLimit_ && (connectionStack_.size() >= connectionStackLimit_)) { delete connection; --numTConnections_; diff --git a/lib/cpp/src/thrift/server/TNonblockingServer.h b/lib/cpp/src/thrift/server/TNonblockingServer.h index 65e569dcf03..9f813ed055e 100644 --- a/lib/cpp/src/thrift/server/TNonblockingServer.h +++ b/lib/cpp/src/thrift/server/TNonblockingServer.h @@ -36,6 +36,7 @@ #include #include #include +#include #ifdef HAVE_UNISTD_H #include #endif @@ -259,7 +260,7 @@ class TNonblockingServer : public TServer { * which in turn allows their transports, protocols, processors and handlers * to deallocate and clean up correctly. */ - std::vector activeConnections_; + std::unordered_set activeConnections_; /* */ diff --git a/lib/cpp/src/thrift/transport/TBufferTransports.cpp b/lib/cpp/src/thrift/transport/TBufferTransports.cpp index f7cf8f03932..2d67aff57aa 100644 --- a/lib/cpp/src/thrift/transport/TBufferTransports.cpp +++ b/lib/cpp/src/thrift/transport/TBufferTransports.cpp @@ -256,8 +256,8 @@ void TFramedTransport::flush() { // Slip the frame size into the start of the buffer. sz_hbo = static_cast(wBase_ - (wBuf_.get() + sizeof(sz_nbo))); - sz_nbo = (int32_t)htonl((uint32_t)(sz_hbo)); - memcpy(wBuf_.get(), (uint8_t*)&sz_nbo, sizeof(sz_nbo)); + sz_nbo = static_cast(htonl(static_cast(sz_hbo))); + memcpy(wBuf_.get(), reinterpret_cast(&sz_nbo), sizeof(sz_nbo)); if (sz_hbo > 0) { // Note that we reset wBase_ (with a pad for the frame size) @@ -347,7 +347,7 @@ uint32_t TMemoryBuffer::readAppendToString(std::string& str, uint32_t len) { computeRead(len, &start, &give); // Append to the provided string. - str.append((char*)start, give); + str.append(reinterpret_cast(start), give); return give; } diff --git a/lib/cpp/src/thrift/transport/TBufferTransports.h b/lib/cpp/src/thrift/transport/TBufferTransports.h index f72d8f6bfda..40e2e6b6162 100644 --- a/lib/cpp/src/thrift/transport/TBufferTransports.h +++ b/lib/cpp/src/thrift/transport/TBufferTransports.h @@ -269,6 +269,11 @@ class TBufferedTransport : public TVirtualTransport // Pad the buffer so we can insert the size later. int32_t pad = 0; - this->write((uint8_t*)&pad, sizeof(pad)); + this->write(reinterpret_cast(&pad), sizeof(pad)); } std::shared_ptr transport_; @@ -463,7 +468,7 @@ class TMemoryBuffer : public TVirtualTransport { if (buf == nullptr && size != 0) { assert(owner); - buf = (uint8_t*)std::malloc(size); + buf = static_cast(std::malloc(size)); if (buf == nullptr) { throw std::bad_alloc(); } @@ -588,7 +593,7 @@ class TMemoryBuffer : public TVirtualTransport { uint8_t* buf; uint32_t sz; getBuffer(&buf, &sz); - return std::string((char*)buf, (std::string::size_type)sz); + return {reinterpret_cast(buf), static_cast(sz)}; } void appendBufferToString(std::string& str) { @@ -598,7 +603,7 @@ class TMemoryBuffer : public TVirtualTransport { uint8_t* buf; uint32_t sz; getBuffer(&buf, &sz); - str.append((char*)buf, sz); + str.append(reinterpret_cast(buf), sz); } void resetBuffer() { diff --git a/lib/cpp/src/thrift/transport/TFileTransport.cpp b/lib/cpp/src/thrift/transport/TFileTransport.cpp index dd7d22925ff..3f4d812c567 100644 --- a/lib/cpp/src/thrift/transport/TFileTransport.cpp +++ b/lib/cpp/src/thrift/transport/TFileTransport.cpp @@ -55,8 +55,6 @@ namespace transport { using std::shared_ptr; using std::cerr; -using std::cout; -using std::endl; using std::string; using namespace apache::thrift::protocol; using namespace apache::thrift::concurrency; @@ -1032,7 +1030,7 @@ void TFileProcessor::process(uint32_t numEvents, bool tail) { break; } } catch (TException& te) { - cerr << te.what() << endl; + cerr << te.what() << '\n'; break; } } @@ -1060,7 +1058,7 @@ void TFileProcessor::processChunk() { } catch (TEOFException&) { break; } catch (TException& te) { - cerr << te.what() << endl; + cerr << te.what() << '\n'; break; } } diff --git a/lib/cpp/src/thrift/transport/TFileTransport.h b/lib/cpp/src/thrift/transport/TFileTransport.h index 608cff18411..902d9061df8 100644 --- a/lib/cpp/src/thrift/transport/TFileTransport.h +++ b/lib/cpp/src/thrift/transport/TFileTransport.h @@ -123,7 +123,7 @@ typedef struct readState { class TFileTransportBuffer { public: TFileTransportBuffer(uint32_t size); - ~TFileTransportBuffer(); + virtual ~TFileTransportBuffer(); bool addEvent(eventInfo* event); eventInfo* getNext(); diff --git a/lib/cpp/src/thrift/transport/THttpServer.cpp b/lib/cpp/src/thrift/transport/THttpServer.cpp index 91a1c39afcd..6fc2816748c 100644 --- a/lib/cpp/src/thrift/transport/THttpServer.cpp +++ b/lib/cpp/src/thrift/transport/THttpServer.cpp @@ -25,7 +25,7 @@ #include #include #if defined(_MSC_VER) || defined(__MINGW32__) - #include + #include #endif using std::string; diff --git a/lib/cpp/src/thrift/transport/TPipeServer.cpp b/lib/cpp/src/thrift/transport/TPipeServer.cpp index e4234b180b5..fd1aeee9514 100644 --- a/lib/cpp/src/thrift/transport/TPipeServer.cpp +++ b/lib/cpp/src/thrift/transport/TPipeServer.cpp @@ -27,8 +27,8 @@ #ifdef _WIN32 #include #include -#include -#include +#include +#include #include #endif //_WIN32 diff --git a/lib/cpp/src/thrift/transport/TSSLServerSocket.cpp b/lib/cpp/src/thrift/transport/TSSLServerSocket.cpp index b20c174087d..9e9fe976eaf 100644 --- a/lib/cpp/src/thrift/transport/TSSLServerSocket.cpp +++ b/lib/cpp/src/thrift/transport/TSSLServerSocket.cpp @@ -17,7 +17,7 @@ * under the License. */ -#include +//#include #include #include diff --git a/lib/cpp/src/thrift/transport/TSSLSocket.cpp b/lib/cpp/src/thrift/transport/TSSLSocket.cpp index 26ae2beda44..3dc6585588e 100644 --- a/lib/cpp/src/thrift/transport/TSSLSocket.cpp +++ b/lib/cpp/src/thrift/transport/TSSLSocket.cpp @@ -152,10 +152,12 @@ void cleanupOpenSSL() { #if (OPENSSL_VERSION_NUMBER < OPENSSL_ENGINE_CLEANUP_REQUIRED_BEFORE) ENGINE_cleanup(); // https://www.openssl.org/docs/man1.1.0/crypto/ENGINE_cleanup.html - cleanup call is needed before 1.1.0 #endif +#if !defined(OPENSSL_IS_AWSLC) CONF_modules_unload(1); +#endif EVP_cleanup(); CRYPTO_cleanup_all_ex_data(); -#if OPENSSL_VERSION_NUMBER >= 0x10100000 +#if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(OPENSSL_IS_AWSLC) // https://www.openssl.org/docs/man1.1.1/man3/OPENSSL_thread_stop.html OPENSSL_thread_stop(); #else @@ -393,7 +395,7 @@ void TSSLSocket::close() { SSL_free(ssl_); ssl_ = nullptr; handshakeCompleted_ = false; -#if OPENSSL_VERSION_NUMBER >= 0x10100000 +#if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(OPENSSL_IS_AWSLC) // https://www.openssl.org/docs/man1.1.1/man3/OPENSSL_thread_stop.html OPENSSL_thread_stop(); #else @@ -703,7 +705,7 @@ void TSSLSocket::initializeHandshake() { } void TSSLSocket::authorize() { - int rc = SSL_get_verify_result(ssl_); + long rc = SSL_get_verify_result(ssl_); if (rc != X509_V_OK) { // verify authentication result throw TSSLException(string("SSL_get_verify_result(), ") + X509_verify_cert_error_string(rc)); } @@ -873,11 +875,13 @@ unsigned int TSSLSocket::waitForEvent(bool wantRead) { uint64_t TSSLSocketFactory::count_ = 0; Mutex TSSLSocketFactory::mutex_; bool TSSLSocketFactory::manualOpenSSLInitialization_ = false; +bool TSSLSocketFactory::didWeInitializeOpenSSL_ = false; TSSLSocketFactory::TSSLSocketFactory(SSLProtocol protocol) : server_(false) { Guard guard(mutex_); if (count_ == 0) { if (!manualOpenSSLInitialization_) { + didWeInitializeOpenSSL_ = true; initializeOpenSSL(); } randomize(); @@ -890,8 +894,9 @@ TSSLSocketFactory::~TSSLSocketFactory() { Guard guard(mutex_); ctx_.reset(); count_--; - if (count_ == 0 && !manualOpenSSLInitialization_) { + if (count_ == 0 && didWeInitializeOpenSSL_) { cleanupOpenSSL(); + didWeInitializeOpenSSL_ = false; } } diff --git a/lib/cpp/src/thrift/transport/TSSLSocket.h b/lib/cpp/src/thrift/transport/TSSLSocket.h index 5afc571f991..80a68ceabdf 100644 --- a/lib/cpp/src/thrift/transport/TSSLSocket.h +++ b/lib/cpp/src/thrift/transport/TSSLSocket.h @@ -327,7 +327,8 @@ class TSSLSocketFactory { std::shared_ptr access_; static concurrency::Mutex mutex_; static uint64_t count_; - THRIFT_EXPORT static bool manualOpenSSLInitialization_; + /*THRIFT_EXPORT*/ static bool manualOpenSSLInitialization_; // questionable to export a private member + static bool didWeInitializeOpenSSL_; // in that case we also perform de-init void setup(std::shared_ptr ssl); static int passwordCallback(char* password, int size, int, void* data); }; diff --git a/lib/cpp/src/thrift/transport/TServerSocket.cpp b/lib/cpp/src/thrift/transport/TServerSocket.cpp index 7cab0eefa77..ffe9ed3a504 100644 --- a/lib/cpp/src/thrift/transport/TServerSocket.cpp +++ b/lib/cpp/src/thrift/transport/TServerSocket.cpp @@ -73,7 +73,7 @@ // adds problematic macros like min() and max(). Try to work around: #define NOMINMAX #define WIN32_LEAN_AND_MEAN -#include +#include #undef NOMINMAX #undef WIN32_LEAN_AND_MEAN #endif diff --git a/lib/cpp/src/thrift/transport/TWebSocketServer.h b/lib/cpp/src/thrift/transport/TWebSocketServer.h index 7f39f36b95e..2a3e076cf04 100644 --- a/lib/cpp/src/thrift/transport/TWebSocketServer.h +++ b/lib/cpp/src/thrift/transport/TWebSocketServer.h @@ -31,7 +31,7 @@ #include #include #if defined(_MSC_VER) || defined(__MINGW32__) -#include +#include #define THRIFT_strncasecmp(str1, str2, len) _strnicmp(str1, str2, len) #define THRIFT_strcasestr(haystack, needle) StrStrIA(haystack, needle) #else diff --git a/lib/cpp/src/thrift/windows/Operators.h b/lib/cpp/src/thrift/windows/Operators.h index 9b860968002..406e11eb6ec 100644 --- a/lib/cpp/src/thrift/windows/Operators.h +++ b/lib/cpp/src/thrift/windows/Operators.h @@ -29,11 +29,6 @@ namespace thrift { class TEnumIterator; -inline bool operator==(const TEnumIterator&, const TEnumIterator&) { - // Not entirely sure what the test should be here. It is only to enable - // iterator debugging and is not used in release mode. - return true; -} } } // apache::thrift diff --git a/lib/cpp/src/thrift/windows/OverlappedSubmissionThread.h b/lib/cpp/src/thrift/windows/OverlappedSubmissionThread.h index 057f623b99a..7326a9c0e28 100644 --- a/lib/cpp/src/thrift/windows/OverlappedSubmissionThread.h +++ b/lib/cpp/src/thrift/windows/OverlappedSubmissionThread.h @@ -105,7 +105,7 @@ class TOverlappedSubmissionThread : apache::thrift::TNonCopyable { // thread details private: TOverlappedSubmissionThread(); - ~TOverlappedSubmissionThread(); + virtual ~TOverlappedSubmissionThread(); void run(); static unsigned __stdcall thread_proc(void* addr); @@ -122,7 +122,7 @@ class TAutoOverlapThread : apache::thrift::TNonCopyable { public: TAutoOverlapThread() : p(TOverlappedSubmissionThread::acquire_instance()) {} - ~TAutoOverlapThread() { TOverlappedSubmissionThread::release_instance(); } + virtual ~TAutoOverlapThread() { TOverlappedSubmissionThread::release_instance(); } TOverlappedSubmissionThread* operator->() { return p; } }; } diff --git a/lib/cpp/src/thrift/windows/SocketPair.cpp b/lib/cpp/src/thrift/windows/SocketPair.cpp index 2650b37d475..9271b02943b 100644 --- a/lib/cpp/src/thrift/windows/SocketPair.cpp +++ b/lib/cpp/src/thrift/windows/SocketPair.cpp @@ -34,7 +34,7 @@ #include // Win32 -#include +#include int thrift_socketpair(int d, int type, int protocol, THRIFT_SOCKET sv[2]) { THRIFT_UNUSED_VARIABLE(protocol); diff --git a/lib/cpp/src/thrift/windows/Sync.h b/lib/cpp/src/thrift/windows/Sync.h index a5b2ac50f0d..e143b863418 100644 --- a/lib/cpp/src/thrift/windows/Sync.h +++ b/lib/cpp/src/thrift/windows/Sync.h @@ -37,7 +37,7 @@ #define WIN32_LEAN_AND_MEAN #define _THRIFT_UNDEF_WIN32_LEAN_AND_MEAN #endif -#include +#include #ifdef _THRIFT_UNDEF_NOMINMAX #undef NOMINMAX #undef _THRIFT_UNDEF_NOMINMAX @@ -58,7 +58,7 @@ namespace thrift { struct TCriticalSection : apache::thrift::TNonCopyable { CRITICAL_SECTION cs; TCriticalSection() { InitializeCriticalSection(&cs); } - ~TCriticalSection() { DeleteCriticalSection(&cs); } + virtual ~TCriticalSection() { DeleteCriticalSection(&cs); } }; class TAutoCrit : apache::thrift::TNonCopyable { @@ -67,7 +67,7 @@ class TAutoCrit : apache::thrift::TNonCopyable { public: explicit TAutoCrit(TCriticalSection& cs) : cs_(&cs.cs) { EnterCriticalSection(cs_); } - ~TAutoCrit() { LeaveCriticalSection(cs_); } + virtual ~TAutoCrit() { LeaveCriticalSection(cs_); } }; struct TAutoResetEvent : apache::thrift::TNonCopyable { @@ -80,7 +80,7 @@ struct TAutoResetEvent : apache::thrift::TNonCopyable { throw apache::thrift::concurrency::SystemResourceException("CreateEvent failed"); } } - ~TAutoResetEvent() { CloseHandle(h); } + virtual ~TAutoResetEvent() { CloseHandle(h); } }; struct TManualResetEvent : apache::thrift::TNonCopyable { @@ -93,7 +93,7 @@ struct TManualResetEvent : apache::thrift::TNonCopyable { throw apache::thrift::concurrency::SystemResourceException("CreateEvent failed"); } } - ~TManualResetEvent() { CloseHandle(h); } + virtual ~TManualResetEvent() { CloseHandle(h); } }; struct TAutoHandle : apache::thrift::TNonCopyable { diff --git a/lib/cpp/src/thrift/windows/TWinsockSingleton.h b/lib/cpp/src/thrift/windows/TWinsockSingleton.h index a098d2c7144..a8e517aabb9 100644 --- a/lib/cpp/src/thrift/windows/TWinsockSingleton.h +++ b/lib/cpp/src/thrift/windows/TWinsockSingleton.h @@ -54,7 +54,7 @@ class TWinsockSingleton : private apache::thrift::TNonCopyable { TWinsockSingleton(void); public: - ~TWinsockSingleton(void); + virtual ~TWinsockSingleton(void); public: static void create(void); diff --git a/lib/cpp/test/AllProtocolTests.tcc b/lib/cpp/test/AllProtocolTests.tcc index 80a4ea097ab..cb98917d3ea 100644 --- a/lib/cpp/test/AllProtocolTests.tcc +++ b/lib/cpp/test/AllProtocolTests.tcc @@ -25,6 +25,7 @@ #include #include #include +#include #include "GenericHelpers.h" @@ -208,6 +209,9 @@ void testProtocol(const char* protoname) { testNaked("a bit longer than the smallest possible"); testNaked("\x1\x2\x3\x4\x5\x6\x7\x8\x9\xA"); // kinda binary test + testNaked(TUuid("5e2ab188-1726-4e75-a04f-1ed9a6a89c4c")); + testField(TUuid("5e2ab188-1726-4e75-a04f-1ed9a6a89c4c")); + testField(""); testField("short"); testField("borderlinetiny"); diff --git a/lib/cpp/test/Benchmark.cpp b/lib/cpp/test/Benchmark.cpp index 56adac0b203..22ec86c54a6 100644 --- a/lib/cpp/test/Benchmark.cpp +++ b/lib/cpp/test/Benchmark.cpp @@ -53,7 +53,6 @@ int main() { using namespace apache::thrift::transport; using namespace apache::thrift::protocol; using std::cout; - using std::endl; OneOfEach ooe; ooe.im_true = true; @@ -66,6 +65,7 @@ int main() { ooe.some_characters = "JSON THIS! \"\1"; ooe.zomg_unicode = "\xd7\n\a\t"; ooe.base64 = "\1\2\3\255"; + ooe.rfc4122_uuid = apache::thrift::TUuid{"{5e2ab188-1726-4e75-a04f-1ed9a6a89c4c}"}; int num = 100000; std::shared_ptr buf(new TMemoryBuffer(num*1000)); @@ -83,7 +83,7 @@ int main() { ooe.write(&prot); } elapsed = timer.frame(); - cout << "Write big endian: " << num / (1000 * elapsed) << " kHz" << endl; + cout << "Write big endian: " << num / (1000 * elapsed) << " kHz" << '\n'; } buf->getBuffer(&data, &datasize); @@ -99,7 +99,7 @@ int main() { ooe2.read(&prot); } elapsed = timer.frame(); - cout << " Read big endian: " << num / (1000 * elapsed) << " kHz" << endl; + cout << " Read big endian: " << num / (1000 * elapsed) << " kHz" << '\n'; } { @@ -112,7 +112,7 @@ int main() { ooe.write(&prot); } elapsed = timer.frame(); - cout << "Write little endian: " << num / (1000 * elapsed) << " kHz" << endl; + cout << "Write little endian: " << num / (1000 * elapsed) << " kHz" << '\n'; } { @@ -126,7 +126,7 @@ int main() { ooe2.read(&prot); } elapsed = timer.frame(); - cout << " Read little endian: " << num / (1000 * elapsed) << " kHz" << endl; + cout << " Read little endian: " << num / (1000 * elapsed) << " kHz" << '\n'; } { @@ -139,7 +139,7 @@ int main() { ooe.write(&prot); } elapsed = timer.frame(); - cout << "Write big endian: " << num / (1000 * elapsed) << " kHz" << endl; + cout << "Write big endian: " << num / (1000 * elapsed) << " kHz" << '\n'; } { @@ -153,7 +153,7 @@ int main() { ooe2.read(&prot); } elapsed = timer.frame(); - cout << " Read big endian: " << num / (1000 * elapsed) << " kHz" << endl; + cout << " Read big endian: " << num / (1000 * elapsed) << " kHz" << '\n'; } @@ -176,7 +176,7 @@ int main() { listDoublePerf.write(&prot); elapsed = timer.frame(); - cout << "Double write big endian: " << num / (1000 * elapsed) << " kHz" << endl; + cout << "Double write big endian: " << num / (1000 * elapsed) << " kHz" << '\n'; } buf->getBuffer(&data, &datasize); @@ -190,7 +190,7 @@ int main() { listDoublePerf2.read(&prot); elapsed = timer.frame(); - cout << " Double read big endian: " << num / (1000 * elapsed) << " kHz" << endl; + cout << " Double read big endian: " << num / (1000 * elapsed) << " kHz" << '\n'; } { @@ -201,7 +201,7 @@ int main() { listDoublePerf.write(&prot); elapsed = timer.frame(); - cout << "Double write little endian: " << num / (1000 * elapsed) << " kHz" << endl; + cout << "Double write little endian: " << num / (1000 * elapsed) << " kHz" << '\n'; } { @@ -213,7 +213,7 @@ int main() { listDoublePerf2.read(&prot); elapsed = timer.frame(); - cout << " Double read little endian: " << num / (1000 * elapsed) << " kHz" << endl; + cout << " Double read little endian: " << num / (1000 * elapsed) << " kHz" << '\n'; } { @@ -224,7 +224,7 @@ int main() { listDoublePerf.write(&prot); elapsed = timer.frame(); - cout << "Double write big endian: " << num / (1000 * elapsed) << " kHz" << endl; + cout << "Double write big endian: " << num / (1000 * elapsed) << " kHz" << '\n'; } { @@ -236,7 +236,7 @@ int main() { listDoublePerf2.read(&prot); elapsed = timer.frame(); - cout << " Double read big endian: " << num / (1000 * elapsed) << " kHz" << endl; + cout << " Double read big endian: " << num / (1000 * elapsed) << " kHz" << '\n'; } diff --git a/lib/cpp/test/CMakeLists.txt b/lib/cpp/test/CMakeLists.txt index 1117cd9f36a..31acf124404 100644 --- a/lib/cpp/test/CMakeLists.txt +++ b/lib/cpp/test/CMakeLists.txt @@ -47,6 +47,8 @@ set(testgencpp_SOURCES gen-cpp/OneWayService.h gen-cpp/TypedefTest_types.cpp gen-cpp/TypedefTest_types.h + gen-cpp/Thrift5272_types.cpp + gen-cpp/Thrift5272_types.h ThriftTest_extras.cpp DebugProtoTest_extras.cpp ) @@ -82,6 +84,8 @@ set(UnitTest_SOURCES TServerSocketTest.cpp TServerTransportTest.cpp ThrifttReadCheckTests.cpp + TUuidTest.cpp + Thrift5272.cpp ) add_executable(UnitTests ${UnitTest_SOURCES}) @@ -94,6 +98,25 @@ if(MSVC) set_property( TARGET UnitTests APPEND_STRING PROPERTY COMPILE_FLAGS /wd4503 ) endif() +# Test the THRIFT_TUUID_SUPPORT_BOOST_UUID compiler directive globally set on the target +add_executable(UnitTestsUuid + UnitTestMain.cpp + TUuidTestBoost.cpp +) +target_link_libraries(UnitTestsUuid testgencpp ${Boost_LIBRARIES}) +target_link_libraries(UnitTestsUuid thrift) +target_compile_definitions(UnitTestsUuid PUBLIC THRIFT_TUUID_SUPPORT_BOOST_UUID) +add_test(NAME UnitTestsUuid COMMAND UnitTestsUuid) + +# Test not setting the THRIFT_TUUID_SUPPORT_BOOST_UUID compiler directive as with the test above. +# The test does set the directive before including the thrift header to test the behaviour +add_executable(UnitTestsUuidNoDirective + UnitTestMain.cpp + TUuidTestBoostNoDirective.cpp +) +target_link_libraries(UnitTestsUuidNoDirective testgencpp ${Boost_LIBRARIES}) +target_link_libraries(UnitTestsUuidNoDirective thrift) +add_test(NAME UnitTestsUuidNoDirective COMMAND UnitTestsUuidNoDirective) set( TInterruptTest_SOURCES TSocketInterruptTest.cpp @@ -110,7 +133,7 @@ target_link_libraries(TInterruptTest ${Boost_LIBRARIES} ) target_link_libraries(TInterruptTest thrift) -if (NOT MSVC AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND NOT MINGW) +if (NOT MSVC AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD" AND NOT MINGW) target_link_libraries(TInterruptTest -lrt) endif () add_test(NAME TInterruptTest COMMAND TInterruptTest -- "${CMAKE_CURRENT_SOURCE_DIR}/../../../test/keys") @@ -121,7 +144,7 @@ target_link_libraries(TServerIntegrationTest ${Boost_LIBRARIES} ) target_link_libraries(TServerIntegrationTest thrift) -if (NOT MSVC AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND NOT MINGW) +if (NOT MSVC AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD" AND NOT MINGW) target_link_libraries(TServerIntegrationTest -lrt) endif () add_test(NAME TServerIntegrationTest COMMAND TServerIntegrationTest) @@ -324,7 +347,7 @@ target_link_libraries(SecurityTest ${Boost_LIBRARIES} ) target_link_libraries(SecurityTest thrift) -if (NOT MSVC AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND NOT MINGW) +if (NOT MSVC AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD" AND NOT MINGW) target_link_libraries(SecurityTest -lrt) endif () add_test(NAME SecurityTest COMMAND SecurityTest -- "${CMAKE_CURRENT_SOURCE_DIR}/../../../test/keys") @@ -335,7 +358,7 @@ target_link_libraries(SecurityFromBufferTest ${Boost_LIBRARIES} ) target_link_libraries(SecurityFromBufferTest thrift) -if (NOT MSVC AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND NOT MINGW) +if (NOT MSVC AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD" AND NOT MINGW) target_link_libraries(SecurityFromBufferTest -lrt) endif () add_test(NAME SecurityFromBufferTest COMMAND SecurityFromBufferTest -- "${CMAKE_CURRENT_SOURCE_DIR}/../../../test/keys") @@ -349,6 +372,8 @@ endif() # # Common thrift code generation rules # +# files from /test +# add_custom_command(OUTPUT gen-cpp/AnnotationTest_constants.cpp gen-cpp/AnnotationTest_constants.h @@ -360,7 +385,7 @@ add_custom_command(OUTPUT gen-cpp/AnnotationTest_constants.cpp ) add_custom_command(OUTPUT gen-cpp/DebugProtoTest_types.cpp gen-cpp/DebugProtoTest_types.h gen-cpp/EmptyService.cpp gen-cpp/EmptyService.h - COMMAND ${THRIFT_COMPILER} --gen cpp ${PROJECT_SOURCE_DIR}/test/v0.16/DebugProtoTest.thrift + COMMAND ${THRIFT_COMPILER} --gen cpp ${PROJECT_SOURCE_DIR}/test/DebugProtoTest.thrift ) add_custom_command(OUTPUT gen-cpp/EnumTest_types.cpp gen-cpp/EnumTest_types.h @@ -384,13 +409,19 @@ add_custom_command(OUTPUT gen-cpp/Service.cpp gen-cpp/StressTest_types.cpp ) add_custom_command(OUTPUT gen-cpp/SecondService.cpp gen-cpp/ThriftTest_constants.cpp gen-cpp/ThriftTest.cpp gen-cpp/ThriftTest_types.cpp gen-cpp/ThriftTest_types.h - COMMAND ${THRIFT_COMPILER} --gen cpp ${PROJECT_SOURCE_DIR}/test/v0.16/ThriftTest.thrift + COMMAND ${THRIFT_COMPILER} --gen cpp ${PROJECT_SOURCE_DIR}/test/ThriftTest.thrift ) +# files from /lib/cpp/test + add_custom_command(OUTPUT gen-cpp/OneWayService.cpp gen-cpp/OneWayTest_types.h gen-cpp/OneWayService.h COMMAND ${THRIFT_COMPILER} --gen cpp ${CMAKE_CURRENT_SOURCE_DIR}/OneWayTest.thrift ) +add_custom_command(OUTPUT gen-cpp/Thrift5272_types.cpp gen-cpp/Thrift5272_types.h + COMMAND ${THRIFT_COMPILER} --gen cpp ${CMAKE_CURRENT_SOURCE_DIR}/Thrift5272.thrift +) + add_custom_command(OUTPUT gen-cpp/ChildService.cpp gen-cpp/ChildService.h gen-cpp/ParentService.cpp gen-cpp/ParentService.h gen-cpp/proc_types.cpp gen-cpp/proc_types.h COMMAND ${THRIFT_COMPILER} --gen cpp:templates,cob_style ${CMAKE_CURRENT_SOURCE_DIR}/processor/proc.thrift ) diff --git a/lib/cpp/test/DebugProtoTest.cpp b/lib/cpp/test/DebugProtoTest.cpp index 060f3547dd7..1a56e7edee2 100644 --- a/lib/cpp/test/DebugProtoTest.cpp +++ b/lib/cpp/test/DebugProtoTest.cpp @@ -74,6 +74,12 @@ BOOST_AUTO_TEST_CASE(test_debug_proto_1) { " [1] = 2,\n" " [2] = 3,\n" " },\n" + " 15: rfc4122_uuid (uuid) = {\n" + " [raw] = \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\",\n" + " [enc] = \"00000000-0000-0000-0000-000000000000\"\n" + " }\n" + " 16: rfc4122_uuid_list (list) = list[0] {\n" + " },\n" "}"); const std::string result(apache::thrift::ThriftDebugString(*ooe)); @@ -84,6 +90,8 @@ BOOST_AUTO_TEST_CASE(test_debug_proto_1) { static ::std::shared_ptr n; void testCaseSetup_2() { + using apache::thrift::TUuid; + testCaseSetup_1(); n.reset(new Nesting); @@ -98,8 +106,14 @@ void testCaseSetup_2() { "\xb0\xcf\x81\xe2\x84\x8e\x20\xce\x91\x74\x74" "\xce\xb1\xe2\x85\xbd\xce\xba\xc7\x83\xe2\x80" "\xbc"; + n->my_ooe.rfc4122_uuid = TUuid{"{5e2ab188-1726-4e75-a04f-1ed9a6a89c4c}"}; n->my_bonk.type = 31337; n->my_bonk.message = "I am a bonk... xor!"; + + std::vector uuiid_list; + uuiid_list.push_back(TUuid{"{fa1af5ec-fdc2-4355-844a-9f0dbfd00e50}"}); + uuiid_list.push_back(TUuid{"{1beece83-34f4-4fa3-b757-1ad1ac157fe3}"}); + n->my_ooe.rfc4122_uuid_list = uuiid_list; } BOOST_AUTO_TEST_CASE(test_debug_proto_2) { @@ -141,6 +155,20 @@ BOOST_AUTO_TEST_CASE(test_debug_proto_2) { " [1] = 2,\n" " [2] = 3,\n" " },\n" + " 15: rfc4122_uuid (uuid) = {\n" + " [raw] = \"^*\\xb1\\x88\\x17&Nu\\xa0O\\x1e\\xd9\\xa6\\xa8\\x9cL\",\n" + " [enc] = \"5e2ab188-1726-4e75-a04f-1ed9a6a89c4c\"\n" + " }\n" + " 16: rfc4122_uuid_list (list) = list[2] {\n" + "{\n" + " [raw] = [0] = \"\\xfa\\x1a\\xf5\\xec\\xfd\\xc2CU\\x84J\\x9f\\r\\xbf\\xd0\\x0eP\",\n" + " [enc] = \"fa1af5ec-fdc2-4355-844a-9f0dbfd00e50\"\n" + " }\n" + "{\n" + " [raw] = [1] = \"\\x1b\\xee\\xce\\x834\\xf4O\\xa3\\xb7W\\x1a\\xd1\\xac\\x15\\x7f\\xe3\",\n" + " [enc] = \"1beece83-34f4-4fa3-b757-1ad1ac157fe3\"\n" + " }\n" + " },\n" " },\n" "}"); const std::string result(apache::thrift::ThriftDebugString(*n)); @@ -228,6 +256,12 @@ BOOST_AUTO_TEST_CASE(test_debug_proto_3) { " [1] = 2,\n" " [2] = 3,\n" " },\n" + " 15: rfc4122_uuid (uuid) = {\n" + " [raw] = \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\",\n" + " [enc] = \"00000000-0000-0000-0000-000000000000\"\n" + " }\n" + " 16: rfc4122_uuid_list (list) = list[0] {\n" + " },\n" " },\n" " [1] = OneOfEach {\n" " 01: im_true (bool) = true,\n" @@ -259,6 +293,20 @@ BOOST_AUTO_TEST_CASE(test_debug_proto_3) { " [1] = 2,\n" " [2] = 3,\n" " },\n" + " 15: rfc4122_uuid (uuid) = {\n" + " [raw] = \"^*\\xb1\\x88\\x17&Nu\\xa0O\\x1e\\xd9\\xa6\\xa8\\x9cL\",\n" + " [enc] = \"5e2ab188-1726-4e75-a04f-1ed9a6a89c4c\"\n" + " }\n" + " 16: rfc4122_uuid_list (list) = list[2] {\n" + "{\n" + " [raw] = [0] = \"\\xfa\\x1a\\xf5\\xec\\xfd\\xc2CU\\x84J\\x9f\\r\\xbf\\xd0\\x0eP\",\n" + " [enc] = \"fa1af5ec-fdc2-4355-844a-9f0dbfd00e50\"\n" + " }\n" + "{\n" + " [raw] = [1] = \"\\x1b\\xee\\xce\\x834\\xf4O\\xa3\\xb7W\\x1a\\xd1\\xac\\x15\\x7f\\xe3\",\n" + " [enc] = \"1beece83-34f4-4fa3-b757-1ad1ac157fe3\"\n" + " }\n" + " },\n" " },\n" " },\n" " 02: contain (set) = set[3] {\n" diff --git a/lib/cpp/test/GenericHelpers.h b/lib/cpp/test/GenericHelpers.h index bcef9f24252..1eed4e2b517 100644 --- a/lib/cpp/test/GenericHelpers.h +++ b/lib/cpp/test/GenericHelpers.h @@ -23,6 +23,7 @@ #include #include #include +#include /* ClassName Helper for cleaner exceptions */ class ClassNames { @@ -57,6 +58,10 @@ template <> const char* ClassNames::getName() { return "string"; } +template <> +const char* ClassNames::getName() { + return "uuid"; +} /* Generic Protocol I/O function for tests */ class GenericIO { @@ -87,6 +92,10 @@ class GenericIO { return proto->writeString(val); } + static uint32_t write(std::shared_ptr proto, const apache::thrift::TUuid& val) { + return proto->writeUUID(val); + } + /* Read functions */ static uint32_t read(std::shared_ptr proto, int8_t& val) { return proto->readByte(val); } @@ -102,6 +111,10 @@ class GenericIO { static uint32_t read(std::shared_ptr proto, std::string& val) { return proto->readString(val); } + + static uint32_t read(std::shared_ptr proto, apache::thrift::TUuid& val) { + return proto->readUUID(val); + } }; #endif diff --git a/lib/cpp/test/JSONProtoTest.cpp b/lib/cpp/test/JSONProtoTest.cpp index 082c8a28b75..ef3938589ac 100644 --- a/lib/cpp/test/JSONProtoTest.cpp +++ b/lib/cpp/test/JSONProtoTest.cpp @@ -48,6 +48,7 @@ void testCaseSetup_1() { ooe->some_characters = "JSON THIS! \"\1"; ooe->zomg_unicode = "\xd7\n\a\t"; ooe->base64 = "\1\2\3\255"; + ooe->rfc4122_uuid = apache::thrift::TUuid{"00000000-0000-0000-0000-000000000000"}; } BOOST_AUTO_TEST_CASE(test_json_proto_1) { @@ -59,7 +60,8 @@ BOOST_AUTO_TEST_CASE(test_json_proto_1) { "535897931},\"8\":{\"str\":\"JSON THIS! \\\"\\u0001\"},\"9\":{\"str\":\"\xd7\\" "n\\u0007\\t\"},\"10\":{\"tf\":0},\"11\":{\"str\":\"AQIDrQ\"},\"12\":{\"lst\"" ":[\"i8\",3,1,2,3]},\"13\":{\"lst\":[\"i16\",3,1,2,3]},\"14\":{\"lst\":[\"i64" - "\",3,1,2,3]}}"); + "\",3,1,2,3]},\"15\":{\"uid\":\"00000000-0000-0000-0000-000000000000\"},\"16\"" + ":{\"lst\":[\"uid\",0]}}"); const std::string result(apache::thrift::ThriftJSONString(*ooe)); @@ -84,6 +86,11 @@ void testCaseSetup_2() { "\xb0\xcf\x81\xe2\x84\x8e\x20\xce\x91\x74\x74" "\xce\xb1\xe2\x85\xbd\xce\xba\xc7\x83\xe2\x80" "\xbc"; + n->my_ooe.rfc4122_uuid = apache::thrift::TUuid{"5e2ab188-1726-4e75-a04f-1ed9a6a89c4c"}; + std::vector uuiid_list; + uuiid_list.push_back(apache::thrift::TUuid{"{fa1af5ec-fdc2-4355-844a-9f0dbfd00e50}"}); + uuiid_list.push_back(apache::thrift::TUuid{"{1beece83-34f4-4fa3-b757-1ad1ac157fe3}"}); + n->my_ooe.rfc4122_uuid_list = uuiid_list; n->my_bonk.type = 31337; n->my_bonk.message = "I am a bonk... xor!"; } @@ -98,7 +105,9 @@ BOOST_AUTO_TEST_CASE(test_json_proto_2) { "1.6180339887498949},\"8\":{\"str\":\":R (me going \\\"rrrr\\\")\"},\"9\":{" "\"str\":\"ӀⅮΝ Нοⅿоɡгаρℎ Αttαⅽκǃ‼\"},\"10\":{\"tf\":0},\"11\":{\"str\":\"" "AQIDrQ\"},\"12\":{\"lst\":[\"i8\",3,1,2,3]},\"13\":{\"lst\":[\"i16\",3,1,2" - ",3]},\"14\":{\"lst\":[\"i64\",3,1,2,3]}}}}" + ",3]},\"14\":{\"lst\":[\"i64\",3,1,2,3]},\"15\":{\"uid\":\"5e2ab188-1726-" + "4e75-a04f-1ed9a6a89c4c\"},\"16\":{\"lst\":[\"uid\",2,\"fa1af5ec-fdc2-4355-" + "844a-9f0dbfd00e50\",\"1beece83-34f4-4fa3-b757-1ad1ac157fe3\"]}}}}" ); const std::string result(apache::thrift::ThriftJSONString(*n)); @@ -162,12 +171,15 @@ BOOST_AUTO_TEST_CASE(test_json_proto_3) { "},\"7\":{\"dbl\":3.1415926535897931},\"8\":{\"str\":\"JSON THIS! \\\"\\u0001" "\"},\"9\":{\"str\":\"\xd7\\n\\u0007\\t\"},\"10\":{\"tf\":0},\"11\":{\"str\":" "\"AQIDrQ\"},\"12\":{\"lst\":[\"i8\",3,1,2,3]},\"13\":{\"lst\":[\"i16\",3,1,2" - ",3]},\"14\":{\"lst\":[\"i64\",3,1,2,3]}},{\"1\":{\"tf\":1},\"2\":{\"tf\":0}," + ",3]},\"14\":{\"lst\":[\"i64\",3,1,2,3]},\"15\":{\"uid\":\"00000000-0000-0000" + "-0000-000000000000\"},\"16\":{\"lst\":[\"uid\",0]}},{\"1\":{\"tf\":1},\"2\":{\"tf\":0}," "\"3\":{\"i8\":51},\"4\":{\"i16\":16},\"5\":{\"i32\":32},\"6\":{\"i64\":64}," "\"7\":{\"dbl\":1.6180339887498949},\"8\":{\"str\":\":R (me going \\\"rrrr\\\"" ")\"},\"9\":{\"str\":\"ӀⅮΝ Нοⅿоɡгаρℎ Αttαⅽκǃ‼\"},\"10\":{\"tf\":0},\"11\":{" "\"str\":\"AQIDrQ\"},\"12\":{\"lst\":[\"i8\",3,1,2,3]},\"13\":{\"lst\":[\"i16" - "\",3,1,2,3]},\"14\":{\"lst\":[\"i64\",3,1,2,3]}}]},\"2\":{\"set\":[\"lst\",3" + "\",3,1,2,3]},\"14\":{\"lst\":[\"i64\",3,1,2,3]},\"15\":{\"uid\":\"5e2ab188-" + "1726-4e75-a04f-1ed9a6a89c4c\"},\"16\":{\"lst\":[\"uid\",2,\"fa1af5ec-fdc2-4355-" + "844a-9f0dbfd00e50\",\"1beece83-34f4-4fa3-b757-1ad1ac157fe3\"]}}]},\"2\":{\"set\":[\"lst\",3" ",[\"str\",0],[\"str\",2,\"and a one\",\"and a two\"],[\"str\",3,\"then a one" ", two\",\"three!\",\"FOUR!!\"]]},\"3\":{\"map\":[\"str\",\"lst\",3,{\"nothin" "g\":[\"rec\",0],\"poe\":[\"rec\",3,{\"1\":{\"i32\":3},\"2\":{\"str\":\"quoth" @@ -192,6 +204,8 @@ BOOST_AUTO_TEST_CASE(test_json_proto_4) { OneOfEach ooe2; ooe2.read(proto.get()); + BOOST_TEST_INFO("written: " << *ooe); + BOOST_TEST_INFO("read : " << ooe2); BOOST_CHECK(*ooe == ooe2); } @@ -205,6 +219,8 @@ BOOST_AUTO_TEST_CASE(test_json_proto_5) { HolyMoley hm2; hm2.read(proto.get()); + BOOST_TEST_INFO("written: " << *hm); + BOOST_TEST_INFO("read : " << hm2); BOOST_CHECK(*hm == hm2); hm2.big[0].a_bite = 0x00; @@ -230,14 +246,14 @@ BOOST_AUTO_TEST_CASE(test_json_proto_6) { ); std::shared_ptr buffer(new TMemoryBuffer()); - std::shared_ptr proto(new TJSONProtocol(buffer)); + std::shared_ptr proto(new TJSONProtocol(buffer)); dub.write(proto.get()); Doubles dub_1; dub_1.read(proto.get()); const std::string result(apache::thrift::ThriftJSONString(dub)); const std::string result_1(apache::thrift::ThriftJSONString(dub_1)); - + BOOST_CHECK_MESSAGE(!expected_result.compare(result), "Expected:\n" << expected_result << "\nGotten:\n" << result); BOOST_CHECK_MESSAGE(!expected_result.compare(result_1), diff --git a/lib/cpp/test/Makefile.am b/lib/cpp/test/Makefile.am index cd401c0f396..b4f6055722b 100644 --- a/lib/cpp/test/Makefile.am +++ b/lib/cpp/test/Makefile.am @@ -24,12 +24,13 @@ BUILT_SOURCES = gen-cpp/AnnotationTest_types.h \ gen-cpp/OptionalRequiredTest_types.h \ gen-cpp/Recursive_types.h \ gen-cpp/ThriftTest_types.h \ + gen-cpp/Thrift5272_types.h \ gen-cpp/TypedefTest_types.h \ gen-cpp/ChildService.h \ gen-cpp/EmptyService.h \ gen-cpp/ParentService.h \ - gen-cpp/OneWayTest_types.h \ - gen-cpp/OneWayService.h \ + gen-cpp/OneWayTest_types.h \ + gen-cpp/OneWayService.h \ gen-cpp/proc_types.h noinst_LTLIBRARIES = libtestgencpp.la libprocessortest.la @@ -50,6 +51,8 @@ nodist_libtestgencpp_la_SOURCES = \ gen-cpp/ThriftTest_types.h \ gen-cpp/ThriftTest_constants.cpp \ gen-cpp/ThriftTest_constants.h \ + gen-cpp/Thrift5272_types.cpp \ + gen-cpp/Thrift5272_types.h \ gen-cpp/TypedefTest_types.cpp \ gen-cpp/TypedefTest_types.h \ gen-cpp/OneWayService.cpp \ @@ -83,6 +86,8 @@ Benchmark_LDADD = libtestgencpp.la check_PROGRAMS = \ UnitTests \ + UnitTestsUuid \ + UnitTestsUuidNoDirective \ TFDTransportTest \ TPipedTransportTest \ DebugProtoTest \ @@ -102,7 +107,7 @@ check_PROGRAMS = \ OpenSSLManualInitTest \ EnumTest \ RenderedDoubleConstantsTest \ - AnnotationTest + AnnotationTest if AMX_HAVE_LIBEVENT noinst_PROGRAMS += \ @@ -131,7 +136,9 @@ UnitTests_SOURCES = \ TServerSocketTest.cpp \ TServerTransportTest.cpp \ TTransportCheckThrow.h \ - ThrifttReadCheckTests.cpp + ThrifttReadCheckTests.cpp \ + Thrift5272.cpp \ + TUuidTest.cpp UnitTests_LDADD = \ libtestgencpp.la \ @@ -139,6 +146,30 @@ UnitTests_LDADD = \ $(BOOST_SYSTEM_LDADD) \ $(BOOST_THREAD_LDADD) +UnitTestsUuid_SOURCES = \ + UnitTestMain.cpp \ + TUuidTestBoost.cpp + +UnitTestsUuid_LDADD = \ + libtestgencpp.la \ + $(BOOST_TEST_LDADD) \ + $(BOOST_SYSTEM_LDADD) \ + $(BOOST_THREAD_LDADD) + +UnitTestsUuid_CPPFLAGS = \ + $(AM_CPPFLAGS) \ + -DTHRIFT_TUUID_SUPPORT_BOOST_UUID + +UnitTestsUuidNoDirective_SOURCES = \ + UnitTestMain.cpp \ + TUuidTestBoostNoDirective.cpp + +UnitTestsUuidNoDirective_LDADD = \ + libtestgencpp.la \ + $(BOOST_TEST_LDADD) \ + $(BOOST_SYSTEM_LDADD) \ + $(BOOST_THREAD_LDADD) + TInterruptTest_SOURCES = \ TSocketInterruptTest.cpp \ TSSLSocketInterruptTest.cpp @@ -382,17 +413,18 @@ OpenSSLManualInitTest_LDADD = \ # # Common thrift code generation rules # +# files from /test +# gen-cpp/AnnotationTest_constants.cpp gen-cpp/AnnotationTest_constants.h gen-cpp/AnnotationTest_types.cpp gen-cpp/AnnotationTest_types.h: $(top_srcdir)/test/AnnotationTest.thrift $(THRIFT) --gen cpp $< -gen-cpp/DebugProtoTest_types.cpp gen-cpp/DebugProtoTest_types.h gen-cpp/EmptyService.cpp gen-cpp/EmptyService.h: $(top_srcdir)/test/v0.16/DebugProtoTest.thrift +gen-cpp/DebugProtoTest_types.cpp gen-cpp/DebugProtoTest_types.h gen-cpp/EmptyService.cpp gen-cpp/EmptyService.h: $(top_srcdir)/test/DebugProtoTest.thrift $(THRIFT) --gen cpp $< gen-cpp/DoubleConstantsTest_constants.cpp gen-cpp/DoubleConstantsTest_constants.h: $(top_srcdir)/test/DoubleConstantsTest.thrift $(THRIFT) --gen cpp $< - gen-cpp/EnumTest_types.cpp gen-cpp/EnumTest_types.h: $(top_srcdir)/test/EnumTest.thrift $(THRIFT) --gen cpp $< @@ -408,12 +440,17 @@ gen-cpp/Recursive_types.cpp gen-cpp/Recursive_types.h: $(top_srcdir)/test/Recurs gen-cpp/Service.cpp gen-cpp/StressTest_types.cpp: $(top_srcdir)/test/StressTest.thrift $(THRIFT) --gen cpp $< -gen-cpp/SecondService.cpp gen-cpp/ThriftTest_constants.cpp gen-cpp/ThriftTest.cpp gen-cpp/ThriftTest_types.cpp gen-cpp/ThriftTest_types.h: $(top_srcdir)/test/v0.16/ThriftTest.thrift +gen-cpp/SecondService.cpp gen-cpp/ThriftTest_constants.cpp gen-cpp/ThriftTest.cpp gen-cpp/ThriftTest_types.cpp gen-cpp/ThriftTest_types.h: $(top_srcdir)/test/ThriftTest.thrift $(THRIFT) --gen cpp $< +# files from /lib/cpp/test + gen-cpp/OneWayService.cpp gen-cpp/OneWayTest_types.h gen-cpp/OneWayService.h: OneWayTest.thrift $(THRIFT) --gen cpp $< +gen-cpp/Thrift5272_types.cpp gen-cpp/Thrift5272_types.h: Thrift5272.thrift + $(THRIFT) --gen cpp $< + gen-cpp/ChildService.cpp gen-cpp/ChildService.h gen-cpp/ParentService.cpp gen-cpp/ParentService.h gen-cpp/proc_types.cpp gen-cpp/proc_types.h: processor/proc.thrift $(THRIFT) --gen cpp:templates,cob_style $< @@ -424,6 +461,9 @@ AM_CXXFLAGS = -Wall -Wextra -pedantic clean-local: $(RM) gen-cpp/* +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ concurrency \ processor \ @@ -431,4 +471,6 @@ EXTRA_DIST = \ CMakeLists.txt \ DebugProtoTest_extras.cpp \ ThriftTest_extras.cpp \ - OneWayTest.thrift + OneWayTest.thrift \ + Thrift5272.thrift + diff --git a/lib/cpp/test/OneWayHTTPTest.cpp b/lib/cpp/test/OneWayHTTPTest.cpp index 7823482f1f1..8789c2c8ffb 100644 --- a/lib/cpp/test/OneWayHTTPTest.cpp +++ b/lib/cpp/test/OneWayHTTPTest.cpp @@ -55,9 +55,6 @@ using apache::thrift::transport::TServerSocket; using apache::thrift::transport::TSocket; using apache::thrift::transport::TTransportException; using std::shared_ptr; -using std::cout; -using std::cerr; -using std::endl; using std::string; namespace utf = boost::unit_test; @@ -70,12 +67,12 @@ class OneWayServiceHandler : public onewaytest::OneWayServiceIf { void roundTripRPC() override { #ifdef ENABLE_STDERR_LOGGING - cerr << "roundTripRPC()" << endl; + cerr << "roundTripRPC()" << '\n'; #endif } void oneWayRPC() override { #ifdef ENABLE_STDERR_LOGGING - cerr << "oneWayRPC()" << std::endl ; + cerr << "oneWayRPC()" << '\n'; #endif } }; @@ -201,7 +198,7 @@ BOOST_AUTO_TEST_CASE( JSON_BufferedHTTP ) int port = ss->getPort() ; #ifdef ENABLE_STDERR_LOGGING - cerr << "port " << port << endl ; + cerr << "port " << port << '\n'; #endif { diff --git a/lib/cpp/test/SecurityFromBufferTest.cpp b/lib/cpp/test/SecurityFromBufferTest.cpp index 65ec8b6a26a..32f2378d38b 100644 --- a/lib/cpp/test/SecurityFromBufferTest.cpp +++ b/lib/cpp/test/SecurityFromBufferTest.cpp @@ -109,7 +109,13 @@ struct SecurityFromBufferFixture { shared_ptr pServerSocket; pServerSocketFactory.reset(new TSSLSocketFactory(static_cast(protocol))); - pServerSocketFactory->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"); + #if OPENSSL_VERSION_NUMBER >= 0x10100000L + // OpenSSL 1.1.0 introduced @SECLEVEL. Modern distributions limit TLS 1.0/1.1 + // to @SECLEVEL=0 or 1, so specify it to test all combinations. + pServerSocketFactory->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@SECLEVEL=0"); + #else + pServerSocketFactory->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"); + #endif pServerSocketFactory->loadCertificateFromBuffer(certString("server.crt").c_str()); pServerSocketFactory->loadPrivateKeyFromBuffer(certString("server.key").c_str()); pServerSocketFactory->server(true); @@ -155,6 +161,11 @@ struct SecurityFromBufferFixture { try { pClientSocketFactory.reset(new TSSLSocketFactory(static_cast(protocol))); pClientSocketFactory->authenticate(true); + #if OPENSSL_VERSION_NUMBER >= 0x10100000L + // OpenSSL 1.1.0 introduced @SECLEVEL. Modern distributions limit TLS 1.0/1.1 + // to @SECLEVEL=0 or 1, so specify it to test all combinations. + pClientSocketFactory->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@SECLEVEL=0"); + #endif pClientSocketFactory->loadCertificateFromBuffer(certString("client.crt").c_str()); pClientSocketFactory->loadPrivateKeyFromBuffer(certString("client.key").c_str()); pClientSocketFactory->loadTrustedCertificatesFromBuffer(certString("CA.pem").c_str()); @@ -199,16 +210,15 @@ BOOST_AUTO_TEST_CASE(ssl_security_matrix) { try { // matrix of connection success between client and server with different SSLProtocol selections static_assert(apache::thrift::transport::LATEST == 5, "Mismatch in assumed number of ssl protocols"); - bool ossl1 = (OPENSSL_VERSION_NUMBER < 0x30000000L); bool matrix[apache::thrift::transport::LATEST + 1][apache::thrift::transport::LATEST + 1] = { // server = SSLTLS SSLv2 SSLv3 TLSv1_0 TLSv1_1 TLSv1_2 // client - /* SSLTLS */ { true, false, false, ossl1, ossl1, true }, + /* SSLTLS */ { true, false, false, true, true, true }, /* SSLv2 */ { false, false, false, false, false, false }, /* SSLv3 */ { false, false, true, false, false, false }, - /* TLSv1_0 */ { ossl1, false, false, ossl1, false, false }, - /* TLSv1_1 */ { ossl1, false, false, false, ossl1, false }, + /* TLSv1_0 */ { true, false, false, true, false, false }, + /* TLSv1_1 */ { true, false, false, false, true, false }, /* TLSv1_2 */ { true, false, false, false, false, true } }; diff --git a/lib/cpp/test/SecurityTest.cpp b/lib/cpp/test/SecurityTest.cpp index 06ee8fe57aa..cc71f04793d 100644 --- a/lib/cpp/test/SecurityTest.cpp +++ b/lib/cpp/test/SecurityTest.cpp @@ -108,7 +108,13 @@ struct SecurityFixture shared_ptr pServerSocket; pServerSocketFactory.reset(new TSSLSocketFactory(static_cast(protocol))); - pServerSocketFactory->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"); + #if OPENSSL_VERSION_NUMBER >= 0x10100000L + // OpenSSL 1.1.0 introduced @SECLEVEL. Modern distributions limit TLS 1.0/1.1 + // to @SECLEVEL=0 or 1, so specify it to test all combinations. + pServerSocketFactory->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@SECLEVEL=0:@STRENGTH"); + #else + pServerSocketFactory->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"); + #endif pServerSocketFactory->loadCertificate(certFile("server.crt").string().c_str()); pServerSocketFactory->loadPrivateKey(certFile("server.key").string().c_str()); pServerSocketFactory->server(true); @@ -162,6 +168,11 @@ struct SecurityFixture { pClientSocketFactory.reset(new TSSLSocketFactory(static_cast(protocol))); pClientSocketFactory->authenticate(true); + #if OPENSSL_VERSION_NUMBER >= 0x10100000L + // OpenSSL 1.1.0 introduced @SECLEVEL. Modern distributions limit TLS 1.0/1.1 + // to @SECLEVEL=0 or 1, so specify it to test all combinations. + pClientSocketFactory->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@SECLEVEL=0"); + #endif pClientSocketFactory->loadCertificate(certFile("client.crt").string().c_str()); pClientSocketFactory->loadPrivateKey(certFile("client.key").string().c_str()); pClientSocketFactory->loadTrustedCertificates(certFile("CA.pem").string().c_str()); @@ -221,16 +232,15 @@ BOOST_AUTO_TEST_CASE(ssl_security_matrix) { // matrix of connection success between client and server with different SSLProtocol selections static_assert(apache::thrift::transport::LATEST == 5, "Mismatch in assumed number of ssl protocols"); - bool ossl1 = (OPENSSL_VERSION_NUMBER < 0x30000000L); bool matrix[apache::thrift::transport::LATEST + 1][apache::thrift::transport::LATEST + 1] = { // server = SSLTLS SSLv2 SSLv3 TLSv1_0 TLSv1_1 TLSv1_2 // client - /* SSLTLS */ { true, false, false, ossl1, ossl1, true }, + /* SSLTLS */ { true, false, false, true, true, true }, /* SSLv2 */ { false, false, false, false, false, false }, /* SSLv3 */ { false, false, true, false, false, false }, - /* TLSv1_0 */ { ossl1, false, false, ossl1, false, false }, - /* TLSv1_1 */ { ossl1, false, false, false, ossl1, false }, + /* TLSv1_0 */ { true, false, false, true, false, false }, + /* TLSv1_1 */ { true, false, false, false, true, false }, /* TLSv1_2 */ { true, false, false, false, false, true } }; diff --git a/lib/cpp/test/SpecializationTest.cpp b/lib/cpp/test/SpecializationTest.cpp index 008837d319c..7256c202998 100644 --- a/lib/cpp/test/SpecializationTest.cpp +++ b/lib/cpp/test/SpecializationTest.cpp @@ -26,6 +26,7 @@ BOOST_AUTO_TEST_CASE(test_specialization_1) { ooe.some_characters = "JSON THIS! \"\1"; ooe.zomg_unicode = "\xd7\n\a\t"; ooe.base64 = "\1\2\3\255"; + ooe.rfc4122_uuid = apache::thrift::TUuid{"00000000-0000-0000-0000-000000000000"}; Nesting n; n.my_ooe = ooe; @@ -89,6 +90,8 @@ BOOST_AUTO_TEST_CASE(test_specialization_1) { OneOfEach ooe2; ooe2.read(proto.get()); + BOOST_TEST_INFO("Write: " << ooe); + BOOST_TEST_INFO("Read : " << ooe2); BOOST_CHECK(ooe == ooe2); hm.write(proto.get()); diff --git a/lib/cpp/test/TMemoryBufferTest.cpp b/lib/cpp/test/TMemoryBufferTest.cpp index 2f1aea69411..53e5d15e010 100644 --- a/lib/cpp/test/TMemoryBufferTest.cpp +++ b/lib/cpp/test/TMemoryBufferTest.cpp @@ -36,8 +36,6 @@ using apache::thrift::protocol::TBinaryProtocol; using apache::thrift::transport::TMemoryBuffer; using apache::thrift::transport::TTransportException; using std::shared_ptr; -using std::cout; -using std::endl; using std::string; BOOST_AUTO_TEST_CASE(test_read_write_grow) { diff --git a/lib/cpp/test/TServerSocketTest.cpp b/lib/cpp/test/TServerSocketTest.cpp index 929defa0a89..0860242bc25 100644 --- a/lib/cpp/test/TServerSocketTest.cpp +++ b/lib/cpp/test/TServerSocketTest.cpp @@ -43,7 +43,7 @@ BOOST_AUTO_TEST_CASE(test_bind_to_address) { accepted->close(); sock1.close(); - std::cout << "An error message from getaddrinfo on the console is expected:" << std::endl; + std::cout << "An error message from getaddrinfo on the console is expected:" << '\n'; TServerSocket sock2("257.258.259.260", 0); BOOST_CHECK_THROW(sock2.listen(), TTransportException); sock2.close(); diff --git a/lib/cpp/test/TUuidTest.cpp b/lib/cpp/test/TUuidTest.cpp new file mode 100644 index 00000000000..d2a661581c6 --- /dev/null +++ b/lib/cpp/test/TUuidTest.cpp @@ -0,0 +1,186 @@ +/* + * 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 +#include +#include +#include + +#include + +using apache::thrift::TUuid; + +BOOST_AUTO_TEST_SUITE(TUuidTest) + +BOOST_AUTO_TEST_CASE(construction) { + BOOST_TEST(TUuid().is_nil()); +} + +BOOST_AUTO_TEST_CASE(construction_string_valid) { + const std::string expected_1{"5e2ab188-1726-4e75-a04f-1ed9a6a89c4c"}; + + BOOST_TEST(to_string(TUuid("5e2ab188-1726-4e75-a04f-1ed9a6a89c4c")) == expected_1); + BOOST_TEST(to_string(TUuid("{5e2ab188-1726-4e75-a04f-1ed9a6a89c4c}")) == expected_1); + BOOST_TEST(to_string(TUuid("{5e2ab18817264e75a04f1ed9a6a89c4c}")) == expected_1); + BOOST_TEST(to_string(TUuid("5e2ab18817264e75a04f1ed9a6a89c4c")) == expected_1); +} + +BOOST_AUTO_TEST_CASE(construction_string_invalid) { + // This test also ensures that the constructor does not throw + const std::string expected{"00000000-0000-0000-0000-000000000000"}; + + BOOST_TEST(to_string(TUuid("5e2ab188-1726-4e75-a04f")) == expected); + BOOST_TEST(to_string(TUuid("{}")) == expected); + BOOST_TEST(to_string(TUuid("{5e2ab18817264e75a04f1ed9a6a89c4c")) == expected); + BOOST_TEST(to_string(TUuid("5e2ab18817264e75a04f1ed9a689c4c")) == expected); +} + +BOOST_AUTO_TEST_CASE(compare) { + BOOST_TEST(TUuid("5e2ab188-1726-4e75-a04f-1ed9a6a89c4c") + == TUuid("5e2ab188-1726-4e75-a04f-1ed9a6a89c4c")); + BOOST_TEST(TUuid("5e2ab188-1726-4e75-a04f-1ed9a6a89c4c") + != TUuid("00000000-1726-4e75-a04f-1ed9a6a89c4c")); + BOOST_TEST(TUuid("{5e2ab188-1726-4e75-a04f-1ed9a6a89c4c}") + == TUuid("5e2ab188-1726-4e75-a04f-1ed9a6a89c4c")); + + // This comparison is expected to fail if strcmp is used + TUuid uuid_1{}; + TUuid uuid_2{}; + uuid_2.data()[15] = 0x64; + BOOST_TEST(uuid_1 != uuid_2); +} + +BOOST_AUTO_TEST_CASE(assign_valid) { + TUuid uuid_1{}; + BOOST_TEST(uuid_1.is_nil()); + uuid_1 = TUuid{"5e2ab188-1726-4e75-a04f-1ed9a6a89c4c"}; + BOOST_TEST(!uuid_1.is_nil()); + + BOOST_TEST(uuid_1 == TUuid("5e2ab188-1726-4e75-a04f-1ed9a6a89c4c")); + + uuid_1 = TUuid{"{12345678-1726-4e75-a04f-1ed9a6a89c4c}"}; + BOOST_TEST(uuid_1 != TUuid("5e2ab188-1726-4e75-a04f-1ed9a6a89c4c")); + BOOST_TEST(uuid_1 == TUuid("{12345678-1726-4e75-a04f-1ed9a6a89c4c}")); +} + +BOOST_AUTO_TEST_CASE(assign_invalid) { + TUuid uuid_1{"5e2ab188-1726-4e75-a04f-1ed9a6a89c4c"}; + BOOST_TEST(!uuid_1.is_nil()); + + BOOST_CHECK_NO_THROW(uuid_1 = TUuid{"123"}); + BOOST_TEST(uuid_1.is_nil()); + BOOST_TEST(to_string(uuid_1) == std::string{"00000000-0000-0000-0000-000000000000"}); +} + +BOOST_AUTO_TEST_CASE(swap) { + TUuid uuid_1{"5e2ab188-1726-4e75-a04f-1ed9a6a89c4c"}; + TUuid uuid_2{}; + BOOST_TEST(!uuid_1.is_nil()); + BOOST_TEST(uuid_2.is_nil()); + + using std::swap; + swap(uuid_1, uuid_2); + + BOOST_TEST(uuid_1.is_nil()); + BOOST_TEST(!uuid_2.is_nil()); + + BOOST_TEST(to_string(uuid_1) == std::string{"00000000-0000-0000-0000-000000000000"}); + BOOST_TEST(to_string(uuid_2) == std::string{"5e2ab188-1726-4e75-a04f-1ed9a6a89c4c"}); +} + +BOOST_AUTO_TEST_CASE(begin_end) { + TUuid uuid_1{"5e2ab188-1726-4e75-a04f-1ed9a6a89c4c"}; + BOOST_TEST(std::distance(std::begin(uuid_1), std::end(uuid_1)) == uuid_1.size()); +} + +BOOST_AUTO_TEST_CASE(into_boost_uuid) { + TUuid uuid{"5e2ab188-1726-4e75-a04f-1ed9a6a89c4c"}; + boost::uuids::uuid boost_uuid{}; + BOOST_TEST(boost_uuid.is_nil()); + std::copy(std::begin(uuid), std::end(uuid), boost_uuid.begin()); + BOOST_TEST(!boost_uuid.is_nil()); + BOOST_TEST(boost::uuids::to_string(boost_uuid) == "5e2ab188-1726-4e75-a04f-1ed9a6a89c4c"); + BOOST_TEST(boost::uuids::to_string(boost_uuid) == to_string(uuid)); +} + +BOOST_AUTO_TEST_CASE(from_boost_uuid) { + static boost::uuids::string_generator gen; + boost::uuids::uuid boost_uuid = gen("1f610073-db33-4d21-adf2-75460d4955cc"); + BOOST_TEST(!boost_uuid.is_nil()); + TUuid uuid; + BOOST_TEST(uuid.is_nil()); + + std::copy(std::begin(boost_uuid), std::end(boost_uuid), uuid.begin()); + BOOST_TEST(!uuid.is_nil()); + + BOOST_TEST(to_string(boost_uuid) == to_string(uuid)); +} + +BOOST_AUTO_TEST_CASE(test_byte_order_variant) { + TUuid uuid{"5e2ab188-1726-4e75-a04f-1ed9a6a89c4c"}; + boost::uuids::uuid boost_uuid{}; + BOOST_TEST(boost_uuid.is_nil()); + std::copy(std::begin(uuid), std::end(uuid), boost_uuid.begin()); + BOOST_TEST(!boost_uuid.is_nil()); + BOOST_TEST(boost_uuid.variant() == boost::uuids::uuid::variant_rfc_4122); +} + +BOOST_AUTO_TEST_CASE(test_byte_order_verify_network) { + const TUuid uuid{"{00112233-4455-6677-8899-aabbccddeeff}"}; + + for (uint8_t idx = 0; idx < uuid.size(); ++idx) { + const uint8_t expected = idx * 0x11; + BOOST_TEST(*(std::begin(uuid) + idx) == expected); + } + + const uint8_t test[16] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}; + + TUuid new_uuid; + std::copy(std::begin(test), std::end(test), std::begin(new_uuid)); + + BOOST_TEST(!new_uuid.is_nil()); + BOOST_TEST(to_string(new_uuid) == std::string{"00112233-4455-6677-8899-aabbccddeeff"}); + + BOOST_TEST(new_uuid == uuid); +} + +BOOST_AUTO_TEST_CASE(test_character_buffer) { + + const uint8_t test[16] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}; + + const TUuid uuid{test}; + + BOOST_TEST(to_string(uuid) == std::string{"00112233-4455-6677-8899-aabbccddeeff"}); +} + +BOOST_AUTO_TEST_CASE(test_boost_buffer) { + + static boost::uuids::string_generator gen; + boost::uuids::uuid boost_uuid = gen("1f610073-db33-4d21-adf2-75460d4955cc"); + BOOST_TEST(!boost_uuid.is_nil()); + + const TUuid uuid{boost_uuid.data}; + + BOOST_TEST(to_string(boost_uuid) == to_string(uuid)); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/lib/cpp/test/TUuidTestBoost.cpp b/lib/cpp/test/TUuidTestBoost.cpp new file mode 100644 index 00000000000..81c35596e32 --- /dev/null +++ b/lib/cpp/test/TUuidTestBoost.cpp @@ -0,0 +1,65 @@ +/* + * 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 +#include +#include +#include + +#include + +using apache::thrift::TUuid; + +BOOST_AUTO_TEST_SUITE(TUuidBoostTest) + +BOOST_AUTO_TEST_CASE(compiler_directive) { + // Test if the macro is set as expected + #ifdef THRIFT_TUUID_SUPPORT_BOOST_UUID + BOOST_TEST(true); + #else + BOOST_TEST(false, "The 'THRIFT_TUUID_SUPPORT_BOOST_UUID' preprocessor directive must be set for these tests"); + #endif // THRIFT_TUUID_SUPPORT_BOOST_UUID +} + +BOOST_AUTO_TEST_CASE(from_boost_uuid_constructor) { + static boost::uuids::string_generator gen; + boost::uuids::uuid boost_uuid{gen("1f610073-db33-4d21-adf2-75460d4955cc")}; + BOOST_TEST(!boost_uuid.is_nil()); + const TUuid uuid{boost_uuid}; + BOOST_TEST(!uuid.is_nil()); + + BOOST_TEST(to_string(boost_uuid) == to_string(uuid)); + BOOST_TEST(to_string(uuid) == std::string{"1f610073-db33-4d21-adf2-75460d4955cc"}); +} + +BOOST_AUTO_TEST_CASE(from_boost_uuid_assignment) { + static boost::uuids::string_generator gen; + boost::uuids::uuid boost_uuid{gen("5cb719a4-cd15-4476-8bcc-f1834b2527ee")}; + BOOST_TEST(!boost_uuid.is_nil()); + TUuid uuid{}; + BOOST_TEST(uuid.is_nil()); + + uuid = boost_uuid; + + BOOST_TEST(to_string(boost_uuid) == to_string(uuid)); + BOOST_TEST(to_string(uuid) == std::string{"5cb719a4-cd15-4476-8bcc-f1834b2527ee"}); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/lib/cpp/test/TUuidTestBoostNoDirective.cpp b/lib/cpp/test/TUuidTestBoostNoDirective.cpp new file mode 100644 index 00000000000..8af9c3572eb --- /dev/null +++ b/lib/cpp/test/TUuidTestBoostNoDirective.cpp @@ -0,0 +1,82 @@ +/* + * 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 + +BOOST_AUTO_TEST_SUITE(TUuidBoostTestNoDirective) + +BOOST_AUTO_TEST_CASE(compiler_directive_not_set) { + // Test if the macro is set as expected + #ifdef THRIFT_TUUID_SUPPORT_BOOST_UUID + BOOST_TEST(false, "The 'THRIFT_TUUID_SUPPORT_BOOST_UUID' preprocessor must NOT be set for these tests"); + #else + BOOST_TEST(true); + #endif // THRIFT_TUUID_SUPPORT_BOOST_UUID +} +BOOST_AUTO_TEST_SUITE_END() + +// This inclusion order is unconventional: This test specifcially tests that +// the THRIFT_TUUID_SUPPORT_BOOST_UUID directive can be set before including the header +// to enable boost::uuid support without causing linking or other errors with +// the compiled thrift library. + +#define THRIFT_TUUID_SUPPORT_BOOST_UUID +#define THRIFT_TUUID_BOOST_CONSTRUCTOR_EXPLICIT + +#include +#include + +#include +using apache::thrift::TUuid; + +BOOST_AUTO_TEST_SUITE(TUuidBoostTestNoDirective) + +BOOST_AUTO_TEST_CASE(compiler_directive_set) { + // Test if the macro is set as expected + #ifdef THRIFT_TUUID_SUPPORT_BOOST_UUID + BOOST_TEST(true); + #else + BOOST_TEST(false, "The 'THRIFT_TUUID_SUPPORT_BOOST_UUID' preprocessor must now be set for these tests"); + #endif // THRIFT_TUUID_SUPPORT_BOOST_UUID +} + +BOOST_AUTO_TEST_CASE(from_boost_uuid_constructor) { + static boost::uuids::string_generator gen; + boost::uuids::uuid boost_uuid{gen("5cb719a4-cd15-4476-8bcc-f1834b2527ee")}; + BOOST_TEST(!boost_uuid.is_nil()); + const TUuid uuid{boost_uuid}; + BOOST_TEST(!uuid.is_nil()); + + BOOST_TEST(to_string(boost_uuid) == to_string(uuid)); + BOOST_TEST(to_string(uuid) == std::string{"5cb719a4-cd15-4476-8bcc-f1834b2527ee"}); +} + +BOOST_AUTO_TEST_CASE(from_boost_uuid_assignment) { + static boost::uuids::string_generator gen; + boost::uuids::uuid boost_uuid{gen("1f610073-db33-4d21-adf2-75460d4955cc")}; + BOOST_TEST(!boost_uuid.is_nil()); + TUuid uuid{}; + BOOST_TEST(uuid.is_nil()); + + uuid = TUuid{boost_uuid}; + + BOOST_TEST(to_string(boost_uuid) == to_string(uuid)); + BOOST_TEST(to_string(uuid) == std::string{"1f610073-db33-4d21-adf2-75460d4955cc"}); +} +BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file diff --git a/lib/cpp/test/Thrift5272.cpp b/lib/cpp/test/Thrift5272.cpp new file mode 100644 index 00000000000..a6b23760adf --- /dev/null +++ b/lib/cpp/test/Thrift5272.cpp @@ -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. + */ + +#include +#include +#include +#include "gen-cpp/Thrift5272_types.h" + +BOOST_AUTO_TEST_SUITE(Thrift5272Test) + +namespace utf = boost::unit_test; + +// Define this env var to enable some logging (in case you need to debug) +#undef ENABLE_STDERR_LOGGING + +using namespace thrift5272; + + +BOOST_AUTO_TEST_CASE( printTo ) +{ + std::stringstream ss; + std::string text; + Meta a = Meta(); + + a.printTo(ss); + text = ss.str(); + BOOST_TEST(text == "Meta(byte_type=0, i8_type=0, i16_type=0, i32_type=0, i64_type=0)"); + + ss.clear(); + ss.str(""); + a.byte_type = 50; + a.i8_type = 50; + a.i16_type = 50; + a.i32_type = 50; + a.i64_type = 50; + a.printTo(ss); + text = ss.str(); + BOOST_TEST(text == "Meta(byte_type=50, i8_type=50, i16_type=50, i32_type=50, i64_type=50)"); + + ss.clear(); + ss.str(""); + a.byte_type = 127; + a.i8_type = 127; + a.i16_type = 127; + a.i32_type = 127; + a.i64_type = 127; + a.printTo(ss); + text = ss.str(); + BOOST_TEST(text == "Meta(byte_type=127, i8_type=127, i16_type=127, i32_type=127, i64_type=127)"); +} + +BOOST_AUTO_TEST_CASE( ostream_handle_int8_to_str ) +{ + int8_t t = 65; + std::ostringstream o; + o << t; + BOOST_TEST(o.str() != "65", "ostingstream handles int8 correctly. let's drop specialization for Thrift5272 from TToString.h."); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/lib/cpp/test/Thrift5272.thrift b/lib/cpp/test/Thrift5272.thrift new file mode 100644 index 00000000000..4be3b6075d0 --- /dev/null +++ b/lib/cpp/test/Thrift5272.thrift @@ -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 cpp thrift5272 + +// a minimal Thrift struct, to test Trift5272.cpp +struct Meta +{ + 1: byte byte_type, // keep using byte, even it'S just an alias for i8 (THRIFT-5153) + 2: i8 i8_type, + 3: i16 i16_type, + 4: i32 i32_type, + 5: i64 i64_type, +} diff --git a/lib/cpp/test/ThrifttReadCheckTests.cpp b/lib/cpp/test/ThrifttReadCheckTests.cpp index eb4ca01b235..09dffe228d3 100644 --- a/lib/cpp/test/ThrifttReadCheckTests.cpp +++ b/lib/cpp/test/ThrifttReadCheckTests.cpp @@ -19,7 +19,6 @@ #define MAX_MESSAGE_SIZE 2 -#include #include #include #include @@ -55,8 +54,6 @@ using apache::thrift::transport::TTransportException; using apache::thrift::transport::TBufferedTransport; using apache::thrift::transport::TFramedTransport; using std::shared_ptr; -using std::cout; -using std::endl; using std::string; using std::memset; using namespace apache::thrift; @@ -171,30 +168,78 @@ BOOST_AUTO_TEST_CASE(test_tthriftbinaryprotocol_read_check_exception) { } BOOST_AUTO_TEST_CASE(test_tthriftcompactprotocol_read_check_exception) { - std::shared_ptr config (new TConfiguration(MAX_MESSAGE_SIZE)); + // Set Max Message Size to 11 since all structs are 12B long + std::shared_ptr config (new TConfiguration(11)); std::shared_ptr transport(new TMemoryBuffer(config)); std::shared_ptr protocol(new TCompactProtocol(transport)); uint32_t val = 0; TType elemType = apache::thrift::protocol::T_STOP; TType elemType1 = apache::thrift::protocol::T_STOP; - TList list(T_I32, 8); + + // This list needs 12B + TList list(T_I32, 12); protocol->writeListBegin(list.elemType_, list.size_); protocol->writeListEnd(); BOOST_CHECK_THROW(protocol->readListBegin(elemType, val), TTransportException); protocol->readListEnd(); - TSet set(T_I32, 8); + // This set needs 12B + TSet set(T_I32, 12); protocol->writeSetBegin(set.elemType_, set.size_); protocol->writeSetEnd(); BOOST_CHECK_THROW(protocol->readSetBegin(elemType, val), TTransportException); protocol->readSetEnd(); - TMap map(T_I32, T_I32, 8); + + // This map needs 12B (2x elem) + TMap map(T_I32, T_I32, 6); protocol->writeMapBegin(map.keyType_, map.valueType_, map.size_); protocol->writeMapEnd(); BOOST_CHECK_THROW(protocol->readMapBegin(elemType, elemType1, val), TTransportException); protocol->readMapEnd(); + + // This string needs 12B (1 for size + str) + string eleven = "1234567890A"; + protocol->writeString(eleven); + BOOST_CHECK_THROW(protocol->readString(eleven), TTransportException); +} + +BOOST_AUTO_TEST_CASE(test_tthriftcompactprotocol_read_check_pass) { + // Set Max Message Size to 12 to check the edge case + std::shared_ptr config (new TConfiguration(12)); + std::shared_ptr transport(new TMemoryBuffer(config)); + std::shared_ptr protocol(new TCompactProtocol(transport)); + + uint32_t val = 0; + TType elemType = apache::thrift::protocol::T_STOP; + TType elemType1 = apache::thrift::protocol::T_STOP; + + // This list needs 12B + TList list(T_I32, 12); + protocol->writeListBegin(list.elemType_, list.size_); + protocol->writeListEnd(); + BOOST_CHECK_NO_THROW(protocol->readListBegin(elemType, val)); + protocol->readListEnd(); + + // This set needs 12B + TSet set(T_I32, 12); + protocol->writeSetBegin(set.elemType_, set.size_); + protocol->writeSetEnd(); + BOOST_CHECK_NO_THROW(protocol->readSetBegin(elemType, val)); + protocol->readSetEnd(); + + // This map needs 12B (2x elem) + TMap map(T_I32, T_I32, 6); + protocol->writeMapBegin(map.keyType_, map.valueType_, map.size_); + protocol->writeMapEnd(); + BOOST_CHECK_NO_THROW(protocol->readMapBegin(elemType, elemType1, val)); + protocol->readMapEnd(); + + // This string needs 12B (1 for size + str) + string eleven = "1234567890A"; + protocol->writeString(eleven); + BOOST_CHECK_NO_THROW(protocol->readString(eleven)); } BOOST_AUTO_TEST_CASE(test_tthriftjsonprotocol_read_check_exception) { diff --git a/lib/cpp/test/ToStringTest.cpp b/lib/cpp/test/ToStringTest.cpp index 736b33c0a5b..cb792df67b7 100644 --- a/lib/cpp/test/ToStringTest.cpp +++ b/lib/cpp/test/ToStringTest.cpp @@ -160,4 +160,13 @@ BOOST_AUTO_TEST_CASE(generated_nested_list_object_to_string) { "ListBonks(bonk=[Bonk(message=a, type=0), Bonk(message=b, type=0)])"); } +BOOST_AUTO_TEST_CASE(generated_uuid_to_string) { + thrift::test::CrazyNesting l; + l.uuid_field = apache::thrift::TUuid{"{4b686716-5f20-4deb-8ce0-9eaf379e8a3d}"}; + + BOOST_CHECK_EQUAL(to_string(l), + "CrazyNesting(string_field=, set_field=, list_field=[], binary_field=, " + "uuid_field=4b686716-5f20-4deb-8ce0-9eaf379e8a3d)"); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/lib/cpp/test/concurrency/Tests.cpp b/lib/cpp/test/concurrency/Tests.cpp index 45054a92ad6..67de7893b5e 100644 --- a/lib/cpp/test/concurrency/Tests.cpp +++ b/lib/cpp/test/concurrency/Tests.cpp @@ -51,52 +51,52 @@ int main(int argc, char** argv) { ThreadFactoryTests threadFactoryTests; - std::cout << "ThreadFactory tests..." << std::endl; + std::cout << "ThreadFactory tests..." << '\n'; const int reapLoops = 2 * WEIGHT; const int reapCount = 100 * WEIGHT; const size_t floodLoops = 3; const size_t floodCount = 500 * WEIGHT; - std::cout << "\t\tThreadFactory reap N threads test: N = " << reapLoops << "x" << reapCount << std::endl; + std::cout << "\t\tThreadFactory reap N threads test: N = " << reapLoops << "x" << reapCount << '\n'; if (!threadFactoryTests.reapNThreads(reapLoops, reapCount)) { - std::cerr << "\t\ttThreadFactory reap N threads FAILED" << std::endl; + std::cerr << "\t\ttThreadFactory reap N threads FAILED" << '\n'; return 1; } - std::cout << "\t\tThreadFactory flood N threads test: N = " << floodLoops << "x" << floodCount << std::endl; + std::cout << "\t\tThreadFactory flood N threads test: N = " << floodLoops << "x" << floodCount << '\n'; if (!threadFactoryTests.floodNTest(floodLoops, floodCount)) { - std::cerr << "\t\ttThreadFactory flood N threads FAILED" << std::endl; + std::cerr << "\t\ttThreadFactory flood N threads FAILED" << '\n'; return 1; } - std::cout << "\t\tThreadFactory synchronous start test" << std::endl; + std::cout << "\t\tThreadFactory synchronous start test" << '\n'; if (!threadFactoryTests.synchStartTest()) { - std::cerr << "\t\ttThreadFactory synchronous start FAILED" << std::endl; + std::cerr << "\t\ttThreadFactory synchronous start FAILED" << '\n'; return 1; } - std::cout << "\t\tThreadFactory monitor timeout test" << std::endl; + std::cout << "\t\tThreadFactory monitor timeout test" << '\n'; if (!threadFactoryTests.monitorTimeoutTest()) { - std::cerr << "\t\ttThreadFactory monitor timeout FAILED" << std::endl; + std::cerr << "\t\ttThreadFactory monitor timeout FAILED" << '\n'; return 1; } } if (runAll || args[0].compare("util") == 0) { - std::cout << "Util tests..." << std::endl; + std::cout << "Util tests..." << '\n'; - std::cout << "\t\tUtil minimum time" << std::endl; + std::cout << "\t\tUtil minimum time" << '\n'; int64_t time00 = std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count(); int64_t time01 = std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count(); - std::cout << "\t\t\tMinimum time: " << time01 - time00 << "ms" << std::endl; + std::cout << "\t\t\tMinimum time: " << time01 - time00 << "ms" << '\n'; time00 = std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count(); time01 = time00; @@ -107,54 +107,54 @@ int main(int argc, char** argv) { time01 = std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count(); } - std::cout << "\t\t\tscall per ms: " << count / (time01 - time00) << std::endl; + std::cout << "\t\t\tscall per ms: " << count / (time01 - time00) << '\n'; } if (runAll || args[0].compare("timer-manager") == 0) { - std::cout << "TimerManager tests..." << std::endl; + std::cout << "TimerManager tests..." << '\n'; - std::cout << "\t\tTimerManager test00" << std::endl; + std::cout << "\t\tTimerManager test00" << '\n'; TimerManagerTests timerManagerTests; if (!timerManagerTests.test00()) { - std::cerr << "\t\tTimerManager tests FAILED" << std::endl; + std::cerr << "\t\tTimerManager tests FAILED" << '\n'; return 1; } - std::cout << "\t\tTimerManager test01" << std::endl; + std::cout << "\t\tTimerManager test01" << '\n'; if (!timerManagerTests.test01()) { - std::cerr << "\t\tTimerManager tests FAILED" << std::endl; + std::cerr << "\t\tTimerManager tests FAILED" << '\n'; return 1; } - std::cout << "\t\tTimerManager test02" << std::endl; + std::cout << "\t\tTimerManager test02" << '\n'; if (!timerManagerTests.test02()) { - std::cerr << "\t\tTimerManager tests FAILED" << std::endl; + std::cerr << "\t\tTimerManager tests FAILED" << '\n'; return 1; } - std::cout << "\t\tTimerManager test03" << std::endl; + std::cout << "\t\tTimerManager test03" << '\n'; if (!timerManagerTests.test03()) { - std::cerr << "\t\tTimerManager tests FAILED" << std::endl; + std::cerr << "\t\tTimerManager tests FAILED" << '\n'; return 1; } - std::cout << "\t\tTimerManager test04" << std::endl; + std::cout << "\t\tTimerManager test04" << '\n'; if (!timerManagerTests.test04()) { - std::cerr << "\t\tTimerManager tests FAILED" << std::endl; + std::cerr << "\t\tTimerManager tests FAILED" << '\n'; return 1; } } if (runAll || args[0].compare("thread-manager") == 0) { - std::cout << "ThreadManager tests..." << std::endl; + std::cout << "ThreadManager tests..." << '\n'; { size_t workerCount = 10 * WEIGHT; @@ -163,26 +163,26 @@ int main(int argc, char** argv) { ThreadManagerTests threadManagerTests; - std::cout << "\t\tThreadManager api test:" << std::endl; + std::cout << "\t\tThreadManager api test:" << '\n'; if (!threadManagerTests.apiTest()) { - std::cerr << "\t\tThreadManager apiTest FAILED" << std::endl; + std::cerr << "\t\tThreadManager apiTest FAILED" << '\n'; return 1; } std::cout << "\t\tThreadManager load test: worker count: " << workerCount - << " task count: " << taskCount << " delay: " << delay << std::endl; + << " task count: " << taskCount << " delay: " << delay << '\n'; if (!threadManagerTests.loadTest(taskCount, delay, workerCount)) { - std::cerr << "\t\tThreadManager loadTest FAILED" << std::endl; + std::cerr << "\t\tThreadManager loadTest FAILED" << '\n'; return 1; } std::cout << "\t\tThreadManager block test: worker count: " << workerCount - << " delay: " << delay << std::endl; + << " delay: " << delay << '\n'; if (!threadManagerTests.blockTest(delay, workerCount)) { - std::cerr << "\t\tThreadManager blockTest FAILED" << std::endl; + std::cerr << "\t\tThreadManager blockTest FAILED" << '\n'; return 1; } } @@ -190,7 +190,7 @@ int main(int argc, char** argv) { if (runAll || args[0].compare("thread-manager-benchmark") == 0) { - std::cout << "ThreadManager benchmark tests..." << std::endl; + std::cout << "ThreadManager benchmark tests..." << '\n'; { @@ -207,19 +207,19 @@ int main(int argc, char** argv) { size_t taskCount = workerCount * tasksPerWorker; std::cout << "\t\tThreadManager load test: worker count: " << workerCount - << " task count: " << taskCount << " delay: " << delay << std::endl; + << " task count: " << taskCount << " delay: " << delay << '\n'; ThreadManagerTests threadManagerTests; if (!threadManagerTests.loadTest(taskCount, delay, workerCount)) { - std::cerr << "\t\tThreadManager loadTest FAILED" << std::endl; + std::cerr << "\t\tThreadManager loadTest FAILED" << '\n'; return 1; } } } } - std::cout << "ALL TESTS PASSED" << std::endl; + std::cout << "ALL TESTS PASSED" << '\n'; return 0; } diff --git a/lib/cpp/test/concurrency/ThreadFactoryTests.h b/lib/cpp/test/concurrency/ThreadFactoryTests.h index 23e46e3de21..a2d55febae1 100644 --- a/lib/cpp/test/concurrency/ThreadFactoryTests.h +++ b/lib/cpp/test/concurrency/ThreadFactoryTests.h @@ -53,7 +53,7 @@ class ThreadFactoryTests { void run() override { Synchronized s(_monitor); - + if (--_count == 0) { _monitor.notify(); } @@ -82,7 +82,7 @@ class ThreadFactoryTests { threadFactory.newThread(shared_ptr(new ReapNTask(*monitor, activeCount)))); } catch (SystemResourceException& e) { std::cout << "\t\t\tfailed to create " << lix* count + tix << " thread " << e.what() - << std::endl; + << '\n'; throw; } } @@ -96,7 +96,7 @@ class ThreadFactoryTests { (*thread)->start(); } catch (SystemResourceException& e) { std::cout << "\t\t\tfailed to start " << lix* count + tix << " thread " << e.what() - << std::endl; + << '\n'; throw; } } @@ -107,11 +107,11 @@ class ThreadFactoryTests { monitor->wait(1000); } } - - std::cout << "\t\t\treaped " << lix* count << " threads" << std::endl; + + std::cout << "\t\t\treaped " << lix* count << " threads" << '\n'; } - std::cout << "\t\t\tSuccess!" << std::endl; + std::cout << "\t\t\tSuccess!" << '\n'; return true; } @@ -202,7 +202,7 @@ class ThreadFactoryTests { bool success = true; - std::cout << "\t\t\t" << (success ? "Success" : "Failure") << "!" << std::endl; + std::cout << "\t\t\t" << (success ? "Success" : "Failure") << "!" << '\n'; return true; } @@ -239,7 +239,7 @@ class ThreadFactoryTests { std::cout << "\t\t\t" << (success ? "Success" : "Failure") << ": minimum required time to elapse " << count * timeout << "ms; actual elapsed time " << endTime - startTime << "ms" - << std::endl; + << '\n'; return success; } @@ -250,14 +250,14 @@ class ThreadFactoryTests { ~FloodTask() override { if (_id % 10000 == 0) { Synchronized sync(_mon); - std::cout << "\t\tthread " << _id << " done" << std::endl; + std::cout << "\t\tthread " << _id << " done" << '\n'; } } void run() override { if (_id % 10000 == 0) { Synchronized sync(_mon); - std::cout << "\t\tthread " << _id << " started" << std::endl; + std::cout << "\t\tthread " << _id << " started" << '\n'; } } const size_t _id; @@ -270,7 +270,7 @@ class ThreadFactoryTests { bool success = false; Monitor mon; - + for (size_t lix = 0; lix < loop; lix++) { ThreadFactory threadFactory = ThreadFactory(); @@ -287,14 +287,14 @@ class ThreadFactoryTests { } catch (TException& e) { std::cout << "\t\t\tfailed to start " << lix* count + tix << " thread " << e.what() - << std::endl; + << '\n'; return success; } } Synchronized sync(mon); - std::cout << "\t\t\tflooded " << (lix + 1) * count << " threads" << std::endl; + std::cout << "\t\t\tflooded " << (lix + 1) * count << " threads" << '\n'; success = true; } diff --git a/lib/cpp/test/concurrency/ThreadManagerTests.h b/lib/cpp/test/concurrency/ThreadManagerTests.h index fee7c7c51a1..b33fc27a5d9 100644 --- a/lib/cpp/test/concurrency/ThreadManagerTests.h +++ b/lib/cpp/test/concurrency/ThreadManagerTests.h @@ -76,7 +76,7 @@ class ThreadManagerTests { { Synchronized s(_monitor); - // std::cout << "Thread " << _count << " completed " << std::endl; + // std::cout << "Thread " << _count << " completed " << '\n'; _count--; if (_count % 10000 == 0) { @@ -131,13 +131,13 @@ class ThreadManagerTests { threadManager->add(*ix); } - std::cout << "\t\t\t\tloaded " << count << " tasks to execute" << std::endl; + std::cout << "\t\t\t\tloaded " << count << " tasks to execute" << '\n'; { Synchronized s(monitor); while (activeCount > 0) { - std::cout << "\t\t\t\tactiveCount = " << activeCount << std::endl; + std::cout << "\t\t\t\tactiveCount = " << activeCount << '\n'; monitor.wait(); } } @@ -184,13 +184,13 @@ class ThreadManagerTests { std::cout << "\t\t\tfirst start: " << firstTime << " Last end: " << lastTime << " min: " << minTime << "ms max: " << maxTime << "ms average: " << averageTime - << "ms" << std::endl; + << "ms" << '\n'; bool success = (time01 - time00) >= ((int64_t)count * timeout) / (int64_t)workerCount; std::cout << "\t\t\t" << (success ? "Success" : "Failure") << "! expected time: " << ((int64_t)count * timeout) / (int64_t)workerCount << "ms elapsed time: " << time01 - time00 - << "ms" << std::endl; + << "ms" << '\n'; return success; } @@ -307,7 +307,7 @@ class ThreadManagerTests { } std::cout << "\t\t\t" - << "Pending tasks " << threadManager->pendingTaskCount() << std::endl; + << "Pending tasks " << threadManager->pendingTaskCount() << '\n'; { Synchronized s(blockMonitor); @@ -323,18 +323,18 @@ class ThreadManagerTests { } std::cout << "\t\t\t" - << "Pending tasks " << threadManager->pendingTaskCount() << std::endl; + << "Pending tasks " << threadManager->pendingTaskCount() << '\n'; try { threadManager->add(extraTask, 1); } catch (TimedOutException&) { std::cout << "\t\t\t" - << "add timed out unexpectedly" << std::endl; + << "add timed out unexpectedly" << '\n'; throw TException("Unexpected timeout adding task"); } catch (TooManyPendingTasksException&) { std::cout << "\t\t\t" - << "add encountered too many pending exepctions" << std::endl; + << "add encountered too many pending exepctions" << '\n'; throw TException("Unexpected timeout adding task"); } @@ -375,10 +375,10 @@ class ThreadManagerTests { } } catch (TException& e) { - std::cout << "ERROR: " << e.what() << std::endl; + std::cout << "ERROR: " << e.what() << '\n'; } - std::cout << "\t\t\t" << (success ? "Success" : "Failure") << std::endl; + std::cout << "\t\t\t" << (success ? "Success" : "Failure") << '\n'; return success; } @@ -390,7 +390,7 @@ class ThreadManagerTests { sleep_(100); int64_t b = std::chrono::duration_cast(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; + std::cerr << "\t\t\texpected 100ms gap, found " << (b-a) << "ms gap instead." << '\n'; return false; } @@ -403,18 +403,18 @@ class ThreadManagerTests { shared_ptr threadManager = ThreadManager::newSimpleThreadManager(1); threadManager->threadFactory(threadFactory); - std::cout << "\t\t\t\tstarting.. " << std::endl; + std::cout << "\t\t\t\tstarting.. " << '\n'; threadManager->start(); 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; } } +#define EXPECT(FUNC, COUNT) { size_t c = FUNC; if (c != COUNT) { std::cerr << "expected " #FUNC" to be " #COUNT ", but was " << c << '\n'; return false; } } EXPECT(threadManager->workerCount(), 1); EXPECT(threadManager->idleWorkerCount(), 1); EXPECT(threadManager->pendingTaskCount(), 0); - std::cout << "\t\t\t\tadd 2nd worker.. " << std::endl; + std::cout << "\t\t\t\tadd 2nd worker.. " << '\n'; threadManager->addWorker(); @@ -422,7 +422,7 @@ class ThreadManagerTests { EXPECT(threadManager->idleWorkerCount(), 2); EXPECT(threadManager->pendingTaskCount(), 0); - std::cout << "\t\t\t\tremove 2nd worker.. " << std::endl; + std::cout << "\t\t\t\tremove 2nd worker.. " << '\n'; threadManager->removeWorker(); @@ -430,7 +430,7 @@ class ThreadManagerTests { EXPECT(threadManager->idleWorkerCount(), 1); EXPECT(threadManager->pendingTaskCount(), 0); - std::cout << "\t\t\t\tremove 1st worker.. " << std::endl; + std::cout << "\t\t\t\tremove 1st worker.. " << '\n'; threadManager->removeWorker(); @@ -438,7 +438,7 @@ class ThreadManagerTests { EXPECT(threadManager->idleWorkerCount(), 0); EXPECT(threadManager->pendingTaskCount(), 0); - std::cout << "\t\t\t\tadd blocking task.. " << std::endl; + std::cout << "\t\t\t\tadd blocking task.. " << '\n'; // We're going to throw a blocking task into the mix Monitor entryMonitor; // signaled when task is running @@ -454,7 +454,7 @@ class ThreadManagerTests { EXPECT(threadManager->idleWorkerCount(), 0); EXPECT(threadManager->pendingTaskCount(), 1); - std::cout << "\t\t\t\tadd other task.. " << std::endl; + std::cout << "\t\t\t\tadd other task.. " << '\n'; shared_ptr otherTask( new ThreadManagerTests::Task(doneMonitor, activeCount, 0)); @@ -465,7 +465,7 @@ class ThreadManagerTests { EXPECT(threadManager->idleWorkerCount(), 0); EXPECT(threadManager->pendingTaskCount(), 2); - std::cout << "\t\t\t\tremove blocking task specifically.. " << std::endl; + std::cout << "\t\t\t\tremove blocking task specifically.. " << '\n'; threadManager->remove(blockingTask); @@ -473,11 +473,11 @@ class ThreadManagerTests { EXPECT(threadManager->idleWorkerCount(), 0); EXPECT(threadManager->pendingTaskCount(), 1); - std::cout << "\t\t\t\tremove next pending task.." << std::endl; + std::cout << "\t\t\t\tremove next pending task.." << '\n'; shared_ptr nextTask = threadManager->removeNextPending(); if (nextTask != otherTask) { - std::cerr << "\t\t\t\t\texpected removeNextPending to return otherTask" << std::endl; + std::cerr << "\t\t\t\t\texpected removeNextPending to return otherTask" << '\n'; return false; } @@ -485,15 +485,15 @@ class ThreadManagerTests { EXPECT(threadManager->idleWorkerCount(), 0); EXPECT(threadManager->pendingTaskCount(), 0); - std::cout << "\t\t\t\tremove next pending task (none left).." << std::endl; + std::cout << "\t\t\t\tremove next pending task (none left).." << '\n'; nextTask = threadManager->removeNextPending(); if (nextTask) { - std::cerr << "\t\t\t\t\texpected removeNextPending to return an empty Runnable" << std::endl; + std::cerr << "\t\t\t\t\texpected removeNextPending to return an empty Runnable" << '\n'; return false; } - std::cout << "\t\t\t\tadd 2 expired tasks and 1 not.." << std::endl; + std::cout << "\t\t\t\tadd 2 expired tasks and 1 not.." << '\n'; shared_ptr expiredTask( new ThreadManagerTests::Task(doneMonitor, activeCount, 0)); @@ -509,28 +509,28 @@ class ThreadManagerTests { EXPECT(threadManager->pendingTaskCount(), 3); EXPECT(threadManager->expiredTaskCount(), 0); - std::cout << "\t\t\t\tremove expired tasks.." << std::endl; + std::cout << "\t\t\t\tremove expired tasks.." << '\n'; if (!m_expired.empty()) { - std::cerr << "\t\t\t\t\texpected m_expired to be empty" << std::endl; + std::cerr << "\t\t\t\t\texpected m_expired to be empty" << '\n'; return false; } threadManager->removeExpiredTasks(); if (m_expired.size() != 2) { - std::cerr << "\t\t\t\t\texpected m_expired to be set" << std::endl; + std::cerr << "\t\t\t\t\texpected m_expired to be set" << '\n'; return false; } if (m_expired.front() != expiredTask) { - std::cerr << "\t\t\t\t\texpected m_expired[0] to be the expired task" << std::endl; + std::cerr << "\t\t\t\t\texpected m_expired[0] to be the expired task" << '\n'; return false; } m_expired.pop_front(); if (m_expired.front() != expiredTask) { - std::cerr << "\t\t\t\t\texpected m_expired[1] to be the expired task" << std::endl; + std::cerr << "\t\t\t\t\texpected m_expired[1] to be the expired task" << '\n'; return false; } @@ -543,23 +543,23 @@ class ThreadManagerTests { EXPECT(threadManager->pendingTaskCount(), 0); EXPECT(threadManager->expiredTaskCount(), 2); - std::cout << "\t\t\t\tadd expired task (again).." << std::endl; + std::cout << "\t\t\t\tadd expired task (again).." << '\n'; threadManager->add(expiredTask, 0, 1); // expires in 1ms sleep_(50); // make sure enough time elapses for it to expire - the shortest expiration time is 1ms - std::cout << "\t\t\t\tadd worker to consume expired task.." << std::endl; + std::cout << "\t\t\t\tadd worker to consume expired task.." << '\n'; threadManager->addWorker(); sleep_(100); // make sure it has time to spin up and expire the task if (m_expired.empty()) { - std::cerr << "\t\t\t\t\texpected m_expired to be set" << std::endl; + std::cerr << "\t\t\t\t\texpected m_expired to be set" << '\n'; return false; } if (m_expired.front() != expiredTask) { - std::cerr << "\t\t\t\t\texpected m_expired to be the expired task" << std::endl; + std::cerr << "\t\t\t\t\texpected m_expired to be the expired task" << '\n'; return false; } @@ -570,16 +570,16 @@ class ThreadManagerTests { EXPECT(threadManager->pendingTaskCount(), 0); EXPECT(threadManager->expiredTaskCount(), 3); - std::cout << "\t\t\t\ttry to remove too many workers" << std::endl; + std::cout << "\t\t\t\ttry to remove too many workers" << '\n'; try { threadManager->removeWorker(2); - std::cerr << "\t\t\t\t\texpected InvalidArgumentException" << std::endl; + std::cerr << "\t\t\t\t\texpected InvalidArgumentException" << '\n'; return false; } catch (const InvalidArgumentException&) { /* expected */ } - std::cout << "\t\t\t\tremove worker.. " << std::endl; + std::cout << "\t\t\t\tremove worker.. " << '\n'; threadManager->removeWorker(); @@ -588,7 +588,7 @@ class ThreadManagerTests { EXPECT(threadManager->pendingTaskCount(), 0); EXPECT(threadManager->expiredTaskCount(), 3); - std::cout << "\t\t\t\tadd blocking task.. " << std::endl; + std::cout << "\t\t\t\tadd blocking task.. " << '\n'; threadManager->add(blockingTask); @@ -596,7 +596,7 @@ class ThreadManagerTests { EXPECT(threadManager->idleWorkerCount(), 0); EXPECT(threadManager->pendingTaskCount(), 1); - std::cout << "\t\t\t\tadd worker.. " << std::endl; + std::cout << "\t\t\t\tadd worker.. " << '\n'; threadManager->addWorker(); { @@ -610,7 +610,7 @@ class ThreadManagerTests { EXPECT(threadManager->idleWorkerCount(), 0); EXPECT(threadManager->pendingTaskCount(), 0); - std::cout << "\t\t\t\tunblock task and remove worker.. " << std::endl; + std::cout << "\t\t\t\tunblock task and remove worker.. " << '\n'; { Synchronized s(blockMonitor); @@ -623,7 +623,7 @@ class ThreadManagerTests { EXPECT(threadManager->idleWorkerCount(), 0); EXPECT(threadManager->pendingTaskCount(), 0); - std::cout << "\t\t\t\tcleanup.. " << std::endl; + std::cout << "\t\t\t\tcleanup.. " << '\n'; blockingTask.reset(); threadManager.reset(); diff --git a/lib/cpp/test/concurrency/TimerManagerTests.h b/lib/cpp/test/concurrency/TimerManagerTests.h index 2d1a2620ab5..9a532320019 100644 --- a/lib/cpp/test/concurrency/TimerManagerTests.h +++ b/lib/cpp/test/concurrency/TimerManagerTests.h @@ -46,7 +46,7 @@ class TimerManagerTests { _success(false), _done(false) {} - ~Task() override { std::cerr << this << std::endl; } + ~Task() override { std::cerr << this << '\n'; } void run() override { @@ -84,7 +84,7 @@ class TimerManagerTests { timerManager.threadFactory(shared_ptr(new ThreadFactory())); timerManager.start(); if (timerManager.state() != TimerManager::STARTED) { - std::cerr << "timerManager is not in the STARTED state, but should be" << std::endl; + std::cerr << "timerManager is not in the STARTED state, but should be" << '\n'; return false; } @@ -104,15 +104,15 @@ class TimerManagerTests { } if (!task->_done) { - std::cerr << "task is not done, but it should have executed" << std::endl; + std::cerr << "task is not done, but it should have executed" << '\n'; return false; } - std::cout << "\t\t\t" << (task->_success ? "Success" : "Failure") << "!" << std::endl; + std::cout << "\t\t\t" << (task->_success ? "Success" : "Failure") << "!" << '\n'; } if (orphanTask->_done) { - std::cerr << "orphan task is done, but it should not have executed" << std::endl; + std::cerr << "orphan task is done, but it should not have executed" << '\n'; return false; } diff --git a/lib/d/Makefile.am b/lib/d/Makefile.am index 013721720b5..6f014c83189 100644 --- a/lib/d/Makefile.am +++ b/lib/d/Makefile.am @@ -192,6 +192,9 @@ TESTS = $(addprefix unittest/debug/, $(d_test_modules)) \ precross: all-local $(MAKE) -C test precross +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ src \ test \ diff --git a/lib/d/src/thrift/base.d b/lib/d/src/thrift/base.d index e843a5c8549..b5cb075bf8d 100644 --- a/lib/d/src/thrift/base.d +++ b/lib/d/src/thrift/base.d @@ -50,7 +50,7 @@ class TCompoundOperationException : TException { /// 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.20.0"; +enum VERSION = "0.22.0"; /** * Functions used for logging inside Thrift. diff --git a/lib/d/test/Makefile.am b/lib/d/test/Makefile.am index 44364f9d97c..28f3f3ec4a0 100644 --- a/lib/d/test/Makefile.am +++ b/lib/d/test/Makefile.am @@ -38,6 +38,8 @@ thrift_test_gen = $(addprefix gen-d/thrift/test/, SecondService.d \ $(thrift_test_gen): $(top_srcdir)/test/v0.16/ThriftTest.thrift $(THRIFT) --gen d $< +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am # The actual test targets. # There just must be some way to reassign a variable without warnings in diff --git a/lib/dart/Makefile.am b/lib/dart/Makefile.am index bd12a92f020..74f1404b663 100644 --- a/lib/dart/Makefile.am +++ b/lib/dart/Makefile.am @@ -28,6 +28,9 @@ clean-local: check-local: all +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + dist-hook: $(RM) -r $(distdir)/.pub find $(distdir) -type d -name ".dart_tool" | xargs $(RM) -r diff --git a/lib/dart/pubspec.yaml b/lib/dart/pubspec.yaml index 7e205483adc..db7b8a6bd54 100644 --- a/lib/dart/pubspec.yaml +++ b/lib/dart/pubspec.yaml @@ -16,7 +16,7 @@ # under the License. name: thrift -version: 0.20.0 +version: 0.22.0 description: > A Dart library for Apache Thrift author: Apache Thrift Developers diff --git a/lib/delphi/src/Thrift.Collections.pas b/lib/delphi/src/Thrift.Collections.pas index 2cb2395adcc..0500d4936a2 100644 --- a/lib/delphi/src/Thrift.Collections.pas +++ b/lib/delphi/src/Thrift.Collections.pas @@ -191,127 +191,105 @@ TThriftListImpl = class( TInterfacedObject, IThriftList, IThriftContaine function ToString : string; override; end; - IThriftHashSet = interface(IThriftContainer) - ['{0923A3B5-D4D4-48A8-91AD-40238E2EAD66}'] - function GetEnumerator: TEnumerator; - function GetIsReadOnly: Boolean; + IThriftHashSet = interface(IThriftContainer) + ['{733E2B57-C374-4359-BBD5-2B9CD8DF737C}'] + function GetEnumerator: TEnumerator; function GetCount: Integer; property Count: Integer read GetCount; - property IsReadOnly: Boolean read GetIsReadOnly; - procedure Add( const item: TValue); + function Add( const item: T) : Boolean; procedure Clear; - function Contains( const item: TValue): Boolean; - procedure CopyTo(var A: TArray; arrayIndex: Integer); - function Remove( const item: TValue ): Boolean; + function Contains( const item: T): Boolean; + function Remove( const item: T): Boolean; end; // compatibility - IHashSet = interface( IThriftHashSet) + IHashSet = interface( IThriftHashSet) ['{C3CF557F-21D9-4524-B899-D3145B0389BB}'] end deprecated 'use IThriftHashSet'; {$WARN SYMBOL_DEPRECATED OFF} - TThriftHashSetImpl = class( TInterfacedObject, IHashSet, IThriftHashSet, IThriftContainer, ISupportsToString) + TThriftHashSetImpl = class( TInterfacedObject, IHashSet, IThriftHashSet, IThriftContainer, ISupportsToString) {$WARN SYMBOL_DEPRECATED DEFAULT} strict private - FDictionary : IThriftDictionary; - FIsReadOnly: Boolean; + FDictionary : TDictionary; // there is no THashSet in older Delphi versions strict protected - function GetEnumerator: TEnumerator; - function GetIsReadOnly: Boolean; + function GetEnumerator: TEnumerator; function GetCount: Integer; property Count: Integer read GetCount; - property IsReadOnly: Boolean read FIsReadOnly; - procedure Add( const item: TValue); + function Add( const item: T) : Boolean; procedure Clear; - function Contains( const item: TValue): Boolean; - procedure CopyTo(var A: TArray; arrayIndex: Integer); - function Remove( const item: TValue ): Boolean; + function Contains( const item: T): Boolean; + function Remove( const item: T): Boolean; public constructor Create( const aCapacity: Integer = 0); overload; - constructor Create( const aCapacity: Integer; const aComparer : IEqualityComparer); overload; + constructor Create( const aCapacity: Integer; const aComparer : IEqualityComparer); overload; + destructor Destroy; override; function ToString : string; override; end; // compatibility - THashSetImpl = class( TThriftHashSetImpl) + THashSetImpl = class( TThriftHashSetImpl) end deprecated 'use TThriftHashSetImpl'; implementation -{ TThriftHashSetImpl. } +{ TThriftHashSetImpl. } -procedure TThriftHashSetImpl.Add( const item: TValue); +function TThriftHashSetImpl.Add( const item: T) : Boolean; begin - if not FDictionary.ContainsKey(item) then - begin - FDictionary.Add( item, 0); - end; + result := not FDictionary.ContainsKey(item); + if result then FDictionary.Add( item, 0); end; -procedure TThriftHashSetImpl.Clear; +procedure TThriftHashSetImpl.Clear; begin FDictionary.Clear; end; -function TThriftHashSetImpl.Contains( const item: TValue): Boolean; +function TThriftHashSetImpl.Contains( const item: T): Boolean; begin Result := FDictionary.ContainsKey(item); end; -procedure TThriftHashSetImpl.CopyTo(var A: TArray; arrayIndex: Integer); -var - i : Integer; - Enumlator : TEnumerator; +constructor TThriftHashSetImpl.Create( const aCapacity: Integer); begin - Enumlator := GetEnumerator; - while Enumlator.MoveNext do - begin - A[arrayIndex] := Enumlator.Current; - Inc(arrayIndex); - end; + inherited Create; + FDictionary := TDictionary.Create( aCapacity); end; -constructor TThriftHashSetImpl.Create( const aCapacity: Integer); +constructor TThriftHashSetImpl.Create( const aCapacity: Integer; const aComparer : IEqualityComparer); begin inherited Create; - FDictionary := TThriftDictionaryImpl.Create( aCapacity); + FDictionary := TDictionary.Create( aCapacity, aComparer); end; -constructor TThriftHashSetImpl.Create( const aCapacity: Integer; const aComparer : IEqualityComparer); + +destructor TThriftHashSetImpl.Destroy; begin - inherited Create; - FDictionary := TThriftDictionaryImpl.Create( aCapacity, aComparer); + FDictionary.Free; + inherited Destroy; end; -function TThriftHashSetImpl.GetCount: Integer; + +function TThriftHashSetImpl.GetCount: Integer; begin Result := FDictionary.Count; end; -function TThriftHashSetImpl.GetEnumerator: TEnumerator; +function TThriftHashSetImpl.GetEnumerator: TEnumerator; begin Result := FDictionary.Keys.GetEnumerator; end; -function TThriftHashSetImpl.GetIsReadOnly: Boolean; -begin - Result := FIsReadOnly; -end; - -function TThriftHashSetImpl.Remove( const item: TValue): Boolean; +function TThriftHashSetImpl.Remove( const item: T): Boolean; begin - Result := False; - if FDictionary.ContainsKey( item ) then - begin - FDictionary.Remove( item ); - Result := not FDictionary.ContainsKey( item ); - end; + Result := FDictionary.ContainsKey( item); + if Result then FDictionary.Remove( item ); end; -function TThriftHashSetImpl.ToString : string; -var elm : TValue; +function TThriftHashSetImpl.ToString : string; +var elm : T; sb : TThriftStringBuilder; first : Boolean; begin @@ -323,7 +301,7 @@ function TThriftHashSetImpl.ToString : string; then first := FALSE else sb.Append(', '); - sb.Append( StringUtils.ToString(elm)); + sb.Append( StringUtils.ToString(elm)); end; sb.Append('}'); Result := sb.ToString; diff --git a/lib/delphi/src/Thrift.Configuration.pas b/lib/delphi/src/Thrift.Configuration.pas index 0cb11af350e..562dba16fef 100644 --- a/lib/delphi/src/Thrift.Configuration.pas +++ b/lib/delphi/src/Thrift.Configuration.pas @@ -33,33 +33,36 @@ interface type IThriftConfiguration = interface - ['{ADD75449-1A67-4B78-9B75-502A1E338CFC}'] - function GetRecursionLimit : Cardinal; - procedure SetRecursionLimit( const value : Cardinal); - function GetMaxFrameSize : Cardinal; - procedure SetMaxFrameSize( const value : Cardinal); - function GetMaxMessageSize : Cardinal; - procedure SetMaxMessageSize( const value : Cardinal); - - property RecursionLimit : Cardinal read GetRecursionLimit write SetRecursionLimit; - property MaxFrameSize : Cardinal read GetMaxFrameSize write SetMaxFrameSize; - property MaxMessageSize : Cardinal read GetMaxMessageSize write SetMaxMessageSize; + ['{666F7848-744A-4746-BDD5-43DC9B1D5520}'] + function GetRecursionLimit : Integer; + procedure SetRecursionLimit( const value : Integer); + function GetMaxFrameSize : Integer; + procedure SetMaxFrameSize( const value : Integer); + function GetMaxMessageSize : Integer; + procedure SetMaxMessageSize( const value : Integer); + + property RecursionLimit : Integer read GetRecursionLimit write SetRecursionLimit; + property MaxFrameSize : Integer read GetMaxFrameSize write SetMaxFrameSize; + property MaxMessageSize : Integer read GetMaxMessageSize write SetMaxMessageSize; end; TThriftConfigurationImpl = class( TInterfacedObject, IThriftConfiguration) + strict private + class procedure ValidateLimitArgument( const value : Integer); inline; + strict protected FRecursionLimit : Cardinal; FMaxFrameSize : Cardinal; FMaxMessageSize : Cardinal; // IThriftConfiguration - function GetRecursionLimit : Cardinal; - procedure SetRecursionLimit( const value : Cardinal); - function GetMaxFrameSize : Cardinal; - procedure SetMaxFrameSize( const value : Cardinal); - function GetMaxMessageSize : Cardinal; - procedure SetMaxMessageSize( const value : Cardinal); + function GetRecursionLimit : Integer; + procedure SetRecursionLimit( const value : Integer); + function GetMaxFrameSize : Integer; + procedure SetMaxFrameSize( const value : Integer); + function GetMaxMessageSize : Integer; + procedure SetMaxMessageSize( const value : Integer); public constructor Create; @@ -82,39 +85,55 @@ constructor TThriftConfigurationImpl.Create; end; -function TThriftConfigurationImpl.GetRecursionLimit: Cardinal; +class procedure TThriftConfigurationImpl.ValidateLimitArgument( const value : Integer); +begin + if value <= 0 // zero makes not much sense either + then raise EArgumentOutOfRangeException.Create('Value must be positive'); +end; + + +function TThriftConfigurationImpl.GetRecursionLimit: Integer; begin - result := FRecursionLimit; + result := FRecursionLimit and MAXINT; + ASSERT( result > 0); end; -procedure TThriftConfigurationImpl.SetRecursionLimit(const value: Cardinal); +procedure TThriftConfigurationImpl.SetRecursionLimit(const value: Integer); begin - FRecursionLimit := value; + ValidateLimitArgument( value); + ASSERT( value > 0); + FRecursionLimit := value and MAXINT; end; -function TThriftConfigurationImpl.GetMaxFrameSize: Cardinal; +function TThriftConfigurationImpl.GetMaxFrameSize: Integer; begin - result := FMaxFrameSize; + result := FMaxFrameSize and MAXINT; + ASSERT( result > 0); end; -procedure TThriftConfigurationImpl.SetMaxFrameSize(const value: Cardinal); +procedure TThriftConfigurationImpl.SetMaxFrameSize(const value: Integer); begin - FMaxFrameSize := value; + ValidateLimitArgument( value); + ASSERT( value > 0); + FMaxFrameSize := value and MAXINT; end; -function TThriftConfigurationImpl.GetMaxMessageSize: Cardinal; +function TThriftConfigurationImpl.GetMaxMessageSize: Integer; begin - result := FMaxMessageSize; + result := FMaxMessageSize and MAXINT; + ASSERT( result > 0); end; -procedure TThriftConfigurationImpl.SetMaxMessageSize(const value: Cardinal); +procedure TThriftConfigurationImpl.SetMaxMessageSize(const value: Integer); begin - FMaxMessageSize := value; + ValidateLimitArgument( value); + ASSERT( value > 0); + FMaxMessageSize := value and MAXINT; end; diff --git a/lib/delphi/src/Thrift.Protocol.Compact.pas b/lib/delphi/src/Thrift.Protocol.Compact.pas index 80f1ce58abd..a8ad53a4192 100644 --- a/lib/delphi/src/Thrift.Protocol.Compact.pas +++ b/lib/delphi/src/Thrift.Protocol.Compact.pas @@ -176,6 +176,7 @@ TFactory = class( TInterfacedObject, IProtocolFactory) procedure WriteI64( const i64: Int64); override; procedure WriteDouble( const dub: Double); override; procedure WriteBinary( const b: TBytes); overload; override; + procedure WriteBinary( const bytes : IThriftBytes); overload; override; procedure WriteUuid( const uuid: TGuid); override; private // unit visible stuff @@ -542,6 +543,14 @@ procedure TCompactProtocolImpl.WriteBinary( const b: TBytes); Transport.Write( b); end; + +procedure TCompactProtocolImpl.WriteBinary( const bytes : IThriftBytes); +begin + WriteVarint32( Cardinal(bytes.Count)); + Transport.Write( bytes.QueryRawDataPtr, 0, bytes.Count); +end; + + procedure TCompactProtocolImpl.WriteUuid( const uuid: TGuid); var network : TGuid; // in network order (Big Endian) begin diff --git a/lib/delphi/src/Thrift.Protocol.pas b/lib/delphi/src/Thrift.Protocol.pas index f5cb454d4c1..969fbcd0788 100644 --- a/lib/delphi/src/Thrift.Protocol.pas +++ b/lib/delphi/src/Thrift.Protocol.pas @@ -28,6 +28,7 @@ interface Classes, SysUtils, Contnrs, + Math, Thrift.Exception, Thrift.Stream, Thrift.Utils, @@ -231,7 +232,6 @@ TProtocolRecursionTrackerImpl = class abstract( TInterfacedObject, IProtocolRe procedure WriteI64( const i64: Int64); procedure WriteDouble( const d: Double); procedure WriteString( const s: string ); - procedure WriteAnsiString( const s: AnsiString); procedure WriteBinary( const b: TBytes); overload; procedure WriteBinary( const b: IThriftBytes); overload; procedure WriteUuid( const uuid: TGuid); @@ -258,7 +258,6 @@ TProtocolRecursionTrackerImpl = class abstract( TInterfacedObject, IProtocolRe function ReadBinaryCOM : IThriftBytes; function ReadUuid: TGuid; function ReadString: string; - function ReadAnsiString: AnsiString; function NextRecursionLevel : IProtocolRecursionTracker; procedure IncrementRecursionDepth; @@ -310,7 +309,6 @@ TProtocolImpl = class abstract( TInterfacedObject, IProtocol) procedure WriteI64( const i64: Int64); virtual; abstract; procedure WriteDouble( const d: Double); virtual; abstract; procedure WriteString( const s: string ); virtual; - procedure WriteAnsiString( const s: AnsiString); virtual; procedure WriteBinary( const b: TBytes); overload; virtual; abstract; procedure WriteUuid( const b: TGuid); virtual; abstract; @@ -335,7 +333,6 @@ TProtocolImpl = class abstract( TInterfacedObject, IProtocol) function ReadBinary: TBytes; virtual; abstract; function ReadUuid: TGuid; virtual; abstract; function ReadString: string; virtual; - function ReadAnsiString: AnsiString; virtual; // provide generic implementation for all derived classes procedure WriteBinary( const bytes : IThriftBytes); overload; virtual; @@ -388,6 +385,7 @@ TThriftBytesImpl = class( TInterfacedObject, IThriftBytes, ISupportsToString) constructor Create; overload; constructor Create( const bytes : TBytes); overload; constructor Create( var bytes : TBytes; const aTakeOwnership : Boolean = FALSE); overload; + constructor Create( const pData : Pointer; const nCount : Integer); overload; function ToString : string; override; end; @@ -441,6 +439,7 @@ TFactory = class( TInterfacedObject, IProtocolFactory) procedure WriteI64( const i64: Int64); override; procedure WriteDouble( const d: Double); override; procedure WriteBinary( const b: TBytes); override; + procedure WriteBinary( const bytes : IThriftBytes); overload; override; procedure WriteUuid( const uuid: TGuid); override; function ReadMessageBegin: TThriftMessage; override; @@ -505,8 +504,8 @@ TProtocolDecorator = class( TProtocolImpl) procedure WriteI64( const i64: Int64); override; procedure WriteDouble( const d: Double); override; procedure WriteString( const s: string ); override; - procedure WriteAnsiString( const s: AnsiString); override; procedure WriteBinary( const b: TBytes); override; + procedure WriteBinary( const bytes : IThriftBytes); overload; override; procedure WriteUuid( const uuid: TGuid); override; function ReadMessageBegin: TThriftMessage; override; @@ -530,7 +529,6 @@ TProtocolDecorator = class( TProtocolImpl) function ReadBinary: TBytes; override; function ReadUuid: TGuid; override; function ReadString: string; override; - function ReadAnsiString: AnsiString; override; end; @@ -682,21 +680,7 @@ function TProtocolImpl.Configuration : IThriftConfiguration; procedure TProtocolImpl.Reset; begin - FTrans.ResetConsumedMessageSize; -end; - -function TProtocolImpl.ReadAnsiString: AnsiString; -var - b : TBytes; - len : Integer; -begin - Result := ''; - b := ReadBinary; - len := Length( b ); - if len > 0 then begin - SetLength( Result, len); - System.Move( b[0], Pointer(Result)^, len ); - end; + FTrans.ResetMessageSizeAndConsumedBytes; end; function TProtocolImpl.ReadString: string; @@ -704,19 +688,6 @@ function TProtocolImpl.ReadString: string; Result := TEncoding.UTF8.GetString( ReadBinary ); end; -procedure TProtocolImpl.WriteAnsiString(const s: AnsiString); -var - b : TBytes; - len : Integer; -begin - len := Length(s); - SetLength( b, len); - if len > 0 then begin - System.Move( Pointer(s)^, b[0], len ); - end; - WriteBinary( b ); -end; - procedure TProtocolImpl.WriteString(const s: string); var b : TBytes; @@ -747,6 +718,8 @@ procedure TProtocolImpl.CheckReadBytesAvailable( const value : TThriftMap); procedure TProtocolImpl.WriteBinary( const bytes : IThriftBytes); +// This implementation works, but is rather inefficient due to the extra memory allocation +// Consider overwriting this for your transport implementation var tmp : TBytes; begin SetLength( tmp, bytes.Count); @@ -802,6 +775,13 @@ constructor TThriftBytesImpl.Create( var bytes : TBytes; const aTakeOwnership : end; +constructor TThriftBytesImpl.Create( const pData : Pointer; const nCount : Integer); +begin + SetLength(FData, Max(nCount,0)); + if Length(FData) > 0 then Move( pData^, FData[0], Length(FData)); +end; + + function TThriftBytesImpl.ToString : string; var sb : TThriftStringBuilder; begin @@ -1105,6 +1085,14 @@ procedure TBinaryProtocolImpl.WriteBinary( const b: TBytes); if iLen > 0 then FTrans.Write(b, 0, iLen); end; +procedure TBinaryProtocolImpl.WriteBinary( const bytes : IThriftBytes); +var iLen : Integer; +begin + iLen := bytes.Count; + WriteI32( iLen); + if iLen > 0 then FTrans.Write( bytes.QueryRawDataPtr, 0, iLen); +end; + procedure TBinaryProtocolImpl.WriteUuid( const uuid: TGuid); var network : TGuid; // in network order (Big Endian) begin @@ -1497,15 +1485,15 @@ procedure TProtocolDecorator.WriteString( const s: string ); end; -procedure TProtocolDecorator.WriteAnsiString( const s: AnsiString); +procedure TProtocolDecorator.WriteBinary( const b: TBytes); begin - FWrappedProtocol.WriteAnsiString( s); + FWrappedProtocol.WriteBinary( b); end; -procedure TProtocolDecorator.WriteBinary( const b: TBytes); +procedure TProtocolDecorator.WriteBinary( const bytes : IThriftBytes); begin - FWrappedProtocol.WriteBinary( b); + FWrappedProtocol.WriteBinary( bytes); end; @@ -1641,12 +1629,6 @@ function TProtocolDecorator.ReadString: string; end; -function TProtocolDecorator.ReadAnsiString: AnsiString; -begin - result := FWrappedProtocol.ReadAnsiString; -end; - - function TProtocolDecorator.GetMinSerializedSize( const aType : TType) : Integer; begin result := FWrappedProtocol.GetMinSerializedSize(aType); diff --git a/lib/delphi/src/Thrift.Stream.pas b/lib/delphi/src/Thrift.Stream.pas index 6c1320d998e..56823312656 100644 --- a/lib/delphi/src/Thrift.Stream.pas +++ b/lib/delphi/src/Thrift.Stream.pas @@ -37,7 +37,7 @@ interface type IThriftStream = interface - ['{3A61A8A6-3639-4B91-A260-EFCA23944F3A}'] + ['{67801A9F-3B85-41CF-9025-D18AC6849B58}'] procedure Write( const buffer: TBytes; offset: Integer; count: Integer); overload; procedure Write( const pBuf : Pointer; offset: Integer; count: Integer); overload; function Read( var buffer: TBytes; offset: Integer; count: Integer): Integer; overload; @@ -47,6 +47,7 @@ interface procedure Flush; function IsOpen: Boolean; function ToArray: TBytes; + function CanSeek : Boolean; function Size : Int64; function Position : Int64; end; @@ -66,6 +67,7 @@ TThriftStreamImpl = class abstract( TInterfacedObject, IThriftStream) procedure Flush; virtual; abstract; function IsOpen: Boolean; virtual; abstract; function ToArray: TBytes; virtual; abstract; + function CanSeek : Boolean; virtual; function Size : Int64; virtual; function Position : Int64; virtual; end; @@ -83,6 +85,7 @@ TThriftStreamAdapterDelphi = class( TThriftStreamImpl) procedure Flush; override; function IsOpen: Boolean; override; function ToArray: TBytes; override; + function CanSeek : Boolean; override; function Size : Int64; override; function Position : Int64; override; public @@ -102,6 +105,7 @@ TThriftStreamAdapterCOM = class( TThriftStreamImpl) procedure Flush; override; function IsOpen: Boolean; override; function ToArray: TBytes; override; + function CanSeek : Boolean; override; function Size : Int64; override; function Position : Int64; override; public @@ -176,6 +180,12 @@ procedure TThriftStreamAdapterCOM.Flush; end; end; +function TThriftStreamAdapterCOM.CanSeek : Boolean; +var statstg: TStatStg; +begin + result := IsOpen and Succeeded( FStream.Stat( statstg, STATFLAG_NONAME)); +end; + function TThriftStreamAdapterCOM.Size : Int64; var statstg: TStatStg; begin @@ -290,6 +300,11 @@ procedure TThriftStreamImpl.Write( const pBuf : Pointer; offset: Integer; count: CheckSizeAndOffset( pBuf, offset+count, offset, count); end; +function TThriftStreamImpl.CanSeek : Boolean; +begin + result := FALSE; // TRUE indicates Size and Position are implemented +end; + function TThriftStreamImpl.Size : Int64; begin ASSERT(FALSE); @@ -332,6 +347,15 @@ procedure TThriftStreamAdapterDelphi.Flush; // nothing to do end; +function TThriftStreamAdapterDelphi.CanSeek : Boolean; +begin + try + result := IsOpen and (FStream.Size >= 0); // throws if not implemented + except + result := FALSE; // seek not implemented + end; +end; + function TThriftStreamAdapterDelphi.Size : Int64; begin result := FStream.Size; diff --git a/lib/delphi/src/Thrift.Transport.MsxmlHTTP.pas b/lib/delphi/src/Thrift.Transport.MsxmlHTTP.pas index b0c7acd22cf..e3886a56bd0 100644 --- a/lib/delphi/src/Thrift.Transport.MsxmlHTTP.pas +++ b/lib/delphi/src/Thrift.Transport.MsxmlHTTP.pas @@ -53,6 +53,8 @@ TMsxmlHTTPClientImpl = class( TEndpointTransportBase, IHTTPClient) FCustomHeaders : IThriftDictionary; function CreateRequest: IXMLHTTPRequest; + class procedure EnsureSuccessHttpStatus( const aRequest : IXMLHTTPRequest); + strict protected function GetIsOpen: Boolean; override; procedure Open(); override; @@ -255,8 +257,9 @@ procedure TMsxmlHTTPClientImpl.SendRequest; ms.Position := 0; xmlhttp.send( IUnknown( TStreamAdapter.Create( ms, soReference ))); FInputStream := nil; + EnsureSuccessHttpStatus(xmlhttp); // throws if not FInputStream := TThriftStreamAdapterCOM.Create( IUnknown( xmlhttp.responseStream) as IStream); - ResetConsumedMessageSize; + ResetMessageSizeAndConsumedBytes; UpdateKnownMessageSize( FInputStream.Size); finally ms.Free; @@ -271,6 +274,20 @@ procedure TMsxmlHTTPClientImpl.Write( const pBuf : Pointer; off, len : Integer); end; +class procedure TMsxmlHTTPClientImpl.EnsureSuccessHttpStatus( const aRequest : IXMLHTTPRequest); +var iStatus : Integer; + sText : string; +begin + if aRequest = nil + then raise TTransportExceptionNotOpen.Create('Invalid HTTP request data'); + + iStatus := aRequest.status; + sText := aRequest.statusText; + + if (200 > iStatus) or (iStatus > 299) + then raise TTransportExceptionEndOfFile.Create('HTTP '+IntToStr(iStatus)+' '+sText); +end; + end. diff --git a/lib/delphi/src/Thrift.Transport.Pipes.pas b/lib/delphi/src/Thrift.Transport.Pipes.pas index 44dfef78030..d3980d79811 100644 --- a/lib/delphi/src/Thrift.Transport.Pipes.pas +++ b/lib/delphi/src/Thrift.Transport.Pipes.pas @@ -679,22 +679,22 @@ procedure THandlePipeStreamImpl.Open; function TPipeTransportBase.GetIsOpen: Boolean; begin - result := (FInputStream <> nil) and (FInputStream.IsOpen) - and (FOutputStream <> nil) and (FOutputStream.IsOpen); + result := (InputStream <> nil) and (InputStream.IsOpen) + and (OutputStream <> nil) and (OutputStream.IsOpen); end; procedure TPipeTransportBase.Open; begin - FInputStream.Open; - FOutputStream.Open; + InputStream.Open; + OutputStream.Open; end; procedure TPipeTransportBase.Close; begin - FInputStream.Close; - FOutputStream.Close; + InputStream.Close; + OutputStream.Close; end; @@ -709,8 +709,8 @@ constructor TNamedPipeTransportClientEndImpl.Create( const aPipeName : string; // Named pipe constructor begin inherited Create( nil, nil, aConfig); - FInputStream := TNamedPipeStreamImpl.Create( aPipeName, TRUE, aShareMode, aSecurityAttributes, aTimeOut, aOpenTimeOut); - FOutputStream := FInputStream; // true for named pipes + SetInputStream( TNamedPipeStreamImpl.Create( aPipeName, TRUE, aShareMode, aSecurityAttributes, aTimeOut, aOpenTimeOut)); + SetOutputStream( InputStream); // true for named pipes end; @@ -721,8 +721,8 @@ constructor TNamedPipeTransportClientEndImpl.Create( const aPipe : THandle; // Named pipe constructor begin inherited Create( nil, nil, aConfig); - FInputStream := THandlePipeStreamImpl.Create( aPipe, aOwnsHandle, TRUE, aTimeOut); - FOutputStream := FInputStream; // true for named pipes + SetInputStream( THandlePipeStreamImpl.Create( aPipe, aOwnsHandle, TRUE, aTimeOut)); + SetOutputStream( InputStream); // true for named pipes end; @@ -761,8 +761,8 @@ constructor TAnonymousPipeTransportImpl.Create( const aPipeRead, aPipeWrite : TH begin inherited Create( nil, nil, aConfig); // overlapped is not supported with AnonPipes, see MSDN - FInputStream := THandlePipeStreamImpl.Create( aPipeRead, aOwnsHandles, FALSE, aTimeout); - FOutputStream := THandlePipeStreamImpl.Create( aPipeWrite, aOwnsHandles, FALSE, aTimeout); + SetInputStream( THandlePipeStreamImpl.Create( aPipeRead, aOwnsHandles, FALSE, aTimeout)); + SetOutputStream( THandlePipeStreamImpl.Create( aPipeWrite, aOwnsHandles, FALSE, aTimeout)); end; @@ -912,7 +912,7 @@ function TAnonymousPipeServerTransportImpl.CreateAnonPipe : Boolean; FReadHandle := hPipe; FWriteHandle := hPipeW; finally - if sd <> nil then LocalFree( Cardinal(sd)); + if sd <> nil then LocalFree( NativeUInt(sd)); end; end; @@ -1117,8 +1117,8 @@ function TNamedPipeServerTransportImpl.CreateNamedPipe : THandle; else raise TTransportExceptionNotOpen.Create('CreateNamedPipe() failed ' + IntToStr(GetLastError)); finally - if sd <> nil then LocalFree( Cardinal( sd)); - if acl <> nil then LocalFree( Cardinal( acl)); + if sd <> nil then LocalFree( NativeUInt(sd)); + if acl <> nil then LocalFree( NativeUInt(acl)); if everyone_sid <> nil then FreeSid(everyone_sid); end; end; diff --git a/lib/delphi/src/Thrift.Transport.WinHTTP.pas b/lib/delphi/src/Thrift.Transport.WinHTTP.pas index 87a230996a2..2d18ca1683a 100644 --- a/lib/delphi/src/Thrift.Transport.WinHTTP.pas +++ b/lib/delphi/src/Thrift.Transport.WinHTTP.pas @@ -51,6 +51,7 @@ TWinHTTPClientImpl = class( TEndpointTransportBase, IHTTPClient) function CreateRequest: IWinHTTPRequest; function SecureProtocolsAsWinHTTPFlags : Cardinal; + class procedure EnsureSuccessHttpStatus( const aRequest : IWinHTTPRequest); strict private type @@ -334,7 +335,8 @@ procedure TWinHTTPClientImpl.SendRequest; end; // we're about to receive a new message, so reset everyting - ResetConsumedMessageSize(-1); + ResetMessageSizeAndConsumedBytes(-1); + EnsureSuccessHttpStatus(http); // throws if not FInputStream := THTTPResponseStream.Create( http); if http.QueryTotalResponseSize( dwSize) // FALSE indicates "no info available" then UpdateKnownMessageSize( dwSize); @@ -349,6 +351,18 @@ procedure TWinHTTPClientImpl.Write( const pBuf : Pointer; off, len : Integer); end; +class procedure TWinHTTPClientImpl.EnsureSuccessHttpStatus( const aRequest : IWinHTTPRequest); +var dwStatus : Cardinal; + sText : string; +begin + if (aRequest <> nil) + then aRequest.QueryHttpStatus( dwStatus, sText) + else raise TTransportExceptionNotOpen.Create('Invalid HTTP request data'); + + if (200 > dwStatus) or (dwStatus > 299) + then raise TTransportExceptionEndOfFile.Create('HTTP '+UIntToStr(dwStatus)+' '+sText); +end; + { TWinHTTPClientImpl.THTTPResponseStream } constructor TWinHTTPClientImpl.THTTPResponseStream.Create( const aRequest : IWinHTTPRequest); diff --git a/lib/delphi/src/Thrift.Transport.pas b/lib/delphi/src/Thrift.Transport.pas index fd088375d42..4ca38315d50 100644 --- a/lib/delphi/src/Thrift.Transport.pas +++ b/lib/delphi/src/Thrift.Transport.pas @@ -68,7 +68,7 @@ interface function Configuration : IThriftConfiguration; function MaxMessageSize : Integer; - procedure ResetConsumedMessageSize( const knownSize : Int64 = -1); + procedure ResetMessageSizeAndConsumedBytes( const knownSize : Int64 = -1); procedure CheckReadBytesAvailable( const numBytes : Int64); procedure UpdateKnownMessageSize( const size : Int64); end; @@ -106,10 +106,10 @@ TEndpointTransportBase = class abstract( TTransportBase, ITransport) function MaxMessageSize : Integer; property RemainingMessageSize : Int64 read FRemainingMessageSize; property KnownMessageSize : Int64 read FKnownMessageSize; - procedure ResetConsumedMessageSize( const newSize : Int64 = -1); + procedure ResetMessageSizeAndConsumedBytes( const newSize : Int64 = -1); procedure UpdateKnownMessageSize(const size : Int64); override; - procedure CheckReadBytesAvailable(const numBytes : Int64); inline; - procedure CountConsumedMessageBytes(const numBytes : Int64); inline; + procedure CheckReadBytesAvailable(const numBytes : Int64); {$IFNDEF Debug} inline; {$ENDIF} + procedure CountConsumedMessageBytes(const numBytes : Int64); {$IFNDEF Debug} inline; {$ENDIF} public constructor Create( const aConfig : IThriftConfiguration); reintroduce; end; @@ -124,7 +124,7 @@ TLayeredTransportBase = class abstract( TTransportBase, ITrans function Configuration : IThriftConfiguration; override; procedure UpdateKnownMessageSize( const size : Int64); override; function MaxMessageSize : Integer; inline; - procedure ResetConsumedMessageSize( const knownSize : Int64 = -1); inline; + procedure ResetMessageSizeAndConsumedBytes( const knownSize : Int64 = -1); inline; procedure CheckReadBytesAvailable( const numBytes : Int64); virtual; public constructor Create( const aTransport: T); reintroduce; @@ -303,14 +303,18 @@ TTcpSocketStreamImpl = class( TThriftStreamImpl) end; TStreamTransportImpl = class( TEndpointTransportBase, IStreamTransport) - strict protected - FInputStream : IThriftStream; - FOutputStream : IThriftStream; + strict private + FInternalInputStream : IThriftStream; + FInternalOutputStream : IThriftStream; + strict protected function GetIsOpen: Boolean; override; - function GetInputStream: IThriftStream; - function GetOutputStream: IThriftStream; + function GetInputStream: IThriftStream; inline; + procedure SetInputStream( const stream : IThriftStream); + + function GetOutputStream: IThriftStream; inline; + procedure SetOutputStream( const stream : IThriftStream); strict protected procedure Open; override; @@ -318,6 +322,8 @@ TStreamTransportImpl = class( TEndpointTransportBase, IStreamTransport) procedure Flush; 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 UpdateKnownMessageSize(const size : Int64); override; public constructor Create( const aInputStream, aOutputStream : IThriftStream; const aConfig : IThriftConfiguration = nil); reintroduce; destructor Destroy; override; @@ -340,6 +346,7 @@ TBufferedStreamImpl = class( TThriftStreamImpl) procedure Flush; override; function IsOpen: Boolean; override; function ToArray: TBytes; override; + function CanSeek : Boolean; override; function Size : Int64; override; function Position : Int64; override; public @@ -545,7 +552,7 @@ constructor TEndpointTransportBase.Create( const aConfig : IThriftConfiguration) then FConfiguration := aConfig else FConfiguration := TThriftConfigurationImpl.Create; - ResetConsumedMessageSize; + ResetMessageSizeAndConsumedBytes; end; @@ -562,7 +569,7 @@ function TEndpointTransportBase.MaxMessageSize : Integer; end; -procedure TEndpointTransportBase.ResetConsumedMessageSize( const newSize : Int64); +procedure TEndpointTransportBase.ResetMessageSizeAndConsumedBytes( const newSize : Int64); // Resets RemainingMessageSize to the configured maximum begin // full reset @@ -583,12 +590,12 @@ procedure TEndpointTransportBase.ResetConsumedMessageSize( const newSize : Int64 procedure TEndpointTransportBase.UpdateKnownMessageSize( const size : Int64); -// Updates RemainingMessageSize to reflect then known real message size (e.g. framed transport). +// Updates RemainingMessageSize to reflect the known real message size (e.g. framed transport). // Will throw if we already consumed too many bytes. var consumed : Int64; begin consumed := KnownMessageSize - RemainingMessageSize; - ResetConsumedMessageSize(size); + ResetMessageSizeAndConsumedBytes(size); CountConsumedMessageBytes(consumed); end; @@ -642,9 +649,9 @@ function TLayeredTransportBase.MaxMessageSize : Integer; end; -procedure TLayeredTransportBase.ResetConsumedMessageSize( const knownSize : Int64 = -1); +procedure TLayeredTransportBase.ResetMessageSizeAndConsumedBytes( const knownSize : Int64 = -1); begin - InnerTransport.ResetConsumedMessageSize( knownSize); + InnerTransport.ResetMessageSizeAndConsumedBytes( knownSize); end; @@ -964,8 +971,8 @@ procedure TSocketImpl.Close; begin inherited Close; - FInputStream := nil; - FOutputStream := nil; + SetInputStream( nil); + SetOutputStream( nil); if FOwnsClient then FreeAndNil( FClient) @@ -997,8 +1004,8 @@ procedure TSocketImpl.InitSocket; FOwnsClient := True; stream := TTcpSocketStreamImpl.Create( FClient, FTimeout); - FInputStream := stream; - FOutputStream := stream; + SetInputStream( stream); + SetOutputStream( stream); end; procedure TSocketImpl.Open; @@ -1026,8 +1033,8 @@ procedure TSocketImpl.Open; FClient.Open; {$ENDIF} - FInputStream := TTcpSocketStreamImpl.Create( FClient, FTimeout); - FOutputStream := FInputStream; + SetInputStream( TTcpSocketStreamImpl.Create( FClient, FTimeout)); + SetOutputStream( InputStream); // same end; { TBufferedStream } @@ -1156,6 +1163,12 @@ procedure TBufferedStreamImpl.Write( const pBuf : Pointer; offset: Integer; coun end; +function TBufferedStreamImpl.CanSeek : Boolean; +begin + result := TRUE; +end; + + function TBufferedStreamImpl.Size : Int64; begin result := FReadBuffer.Size; @@ -1173,45 +1186,57 @@ function TBufferedStreamImpl.Position : Int64; constructor TStreamTransportImpl.Create( const aInputStream, aOutputStream : IThriftStream; const aConfig : IThriftConfiguration); begin inherited Create( aConfig); - FInputStream := aInputStream; - FOutputStream := aOutputStream; + SetInputStream( aInputStream); + SetOutputStream( aOutputStream); end; destructor TStreamTransportImpl.Destroy; begin - FInputStream := nil; - FOutputStream := nil; + SetInputStream( nil); + SetInputStream( nil); inherited; end; procedure TStreamTransportImpl.Close; begin - FInputStream := nil; - FOutputStream := nil; + SetInputStream( nil); + SetInputStream( nil); end; procedure TStreamTransportImpl.Flush; begin - if FOutputStream = nil then begin + if OutputStream = nil then begin raise TTransportExceptionNotOpen.Create('Cannot flush null outputstream' ); end; - FOutputStream.Flush; + OutputStream.Flush; end; function TStreamTransportImpl.GetInputStream: IThriftStream; begin - Result := FInputStream; + Result := FInternalInputStream; end; -function TStreamTransportImpl.GetIsOpen: Boolean; +procedure TStreamTransportImpl.SetInputStream( const stream : IThriftStream); begin - Result := True; + FInternalInputStream := stream; + ResetMessageSizeAndConsumedBytes(-1); // full reset to configured maximum + UpdateKnownMessageSize( -1); // adjust to real stream size end; function TStreamTransportImpl.GetOutputStream: IThriftStream; begin - Result := FOutputStream; + Result := FInternalOutputStream; +end; + +procedure TStreamTransportImpl.SetOutputStream( const stream : IThriftStream); +begin + FInternalOutputStream := stream; +end; + +function TStreamTransportImpl.GetIsOpen: Boolean; +begin + Result := True; end; procedure TStreamTransportImpl.Open; @@ -1221,19 +1246,36 @@ procedure TStreamTransportImpl.Open; function TStreamTransportImpl.Read( const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer): Integer; begin - if FInputStream = nil + if InputStream = nil then raise TTransportExceptionNotOpen.Create('Cannot read from null inputstream' ); - Result := FInputStream.Read( pBuf,buflen, off, len ); + Result := InputStream.Read( pBuf,buflen, off, len ); CountConsumedMessageBytes( result); end; procedure TStreamTransportImpl.Write( const pBuf : Pointer; off, len : Integer); begin - if FOutputStream = nil + if OutputStream = nil then raise TTransportExceptionNotOpen.Create('Cannot write to null outputstream' ); - FOutputStream.Write( pBuf, off, len ); + OutputStream.Write( pBuf, off, len ); +end; + + +procedure TStreamTransportImpl.UpdateKnownMessageSize(const size : Int64); +var adjusted : Int64; +begin + if InputStream = nil + then adjusted := 0 + else begin + adjusted := MaxMessageSize; + if size > 0 + then adjusted := Math.Min( adjusted, size); + if InputStream.CanSeek + then adjusted := Math.Min( adjusted, InputStream.Size); + end; + + inherited UpdateKnownMessageSize( adjusted); end; { TBufferedTransportImpl } diff --git a/lib/delphi/src/Thrift.pas b/lib/delphi/src/Thrift.pas index 6696a195a57..b06d38fbdb8 100644 --- a/lib/delphi/src/Thrift.pas +++ b/lib/delphi/src/Thrift.pas @@ -28,7 +28,7 @@ interface Thrift.Protocol; const - Version = '0.20.0'; + Version = '0.22.0'; type TException = Thrift.Exception.TException; // compatibility alias diff --git a/lib/delphi/test/client.dpr b/lib/delphi/test/client.dpr index eaeeee0a28d..db62995559e 100644 --- a/lib/delphi/test/client.dpr +++ b/lib/delphi/test/client.dpr @@ -24,9 +24,13 @@ program client; uses SysUtils, - DataFactory in 'Performance\DataFactory.pas', - PerfTests in 'Performance\PerfTests.pas', - TestClient in 'TestClient.pas', + ConsoleHelper in 'ConsoleHelper.pas', + TestConstants in 'testsuite\TestConstants.pas', + TestClient in 'testsuite\client\TestClient.pas', + TestLogger in 'testsuite\client\TestLogger.pas', + UnitTests in 'testsuite\client\UnitTests.pas', + PerfTests in 'testsuite\client\Performance\PerfTests.pas', + DataFactory in 'testsuite\client\Performance\DataFactory.pas', Thrift.Test in 'gen-delphi\Thrift.Test.pas', Thrift in '..\src\Thrift.pas', Thrift.Transport in '..\src\Thrift.Transport.pas', diff --git a/lib/delphi/test/client.dproj b/lib/delphi/test/client.dproj index ae6683d992d..ae31ba050e5 100644 --- a/lib/delphi/test/client.dproj +++ b/lib/delphi/test/client.dproj @@ -50,9 +50,13 @@ MainSource - - - + + + + + + + @@ -125,7 +129,7 @@ - --protocol=compact + --protocol=compact diff --git a/lib/delphi/test/codegen/README.md b/lib/delphi/test/codegen/README.md index a0145890f2e..65fbe4e510d 100644 --- a/lib/delphi/test/codegen/README.md +++ b/lib/delphi/test/codegen/README.md @@ -1,28 +1,15 @@ -How to use the test case: +Prerequisites ---------------------------------------------- -- copy and the template batch file -- open the batch file and adjust configuration as necessary -- run the batch - +- a suitable dcc32.exe must be reachable via normal search path +- the Thrift compiler thrift.exe is searched in this order + - under the `compiler` subdir, where debug is preferred over release + - otherwise via normal search path -Configuration: +How to use the test case: ---------------------------------------------- -SVNWORKDIR -should point to the Thrift working copy root - -MY_THRIFT_FILES -can be set to point to a folder with more thrift IDL files. -If you don't have any such files, just leave the setting blank. +- run the POSH script +- if any error messages occur, that's a bad sign +- there may be known but unfixed issues, these are listed accordingly -BIN -Local MSYS binary folder. Your THRIFT.EXE is installed here. -MINGW_BIN -Local MinGW bin folder. Contains DLL files required by THRIFT.EXE - -DCC -Identifies the Delphi Command Line compiler (dcc32.exe) -To be configuired only, if the default is not suitable. - ----------------------------------------------- -*EOF* \ No newline at end of file +*EOF* diff --git a/lib/delphi/test/codegen/run-Pascal-Codegen-Tests.bat.tmpl b/lib/delphi/test/codegen/run-Pascal-Codegen-Tests.bat.tmpl deleted file mode 100644 index 79cf0e3396a..00000000000 --- a/lib/delphi/test/codegen/run-Pascal-Codegen-Tests.bat.tmpl +++ /dev/null @@ -1,177 +0,0 @@ -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 */ -@echo off -if ""=="%1" goto CONFIG -goto HANDLEDIR - -REM ----------------------------------------------------- -:CONFIG -REM ----------------------------------------------------- - -rem * CONFIGURATION BEGIN -rem * configuration settings, adjust as necessary to meet your system setup -set SVNWORKDIR= -set MY_THRIFT_FILES= -set BIN=C:\MSys10\local\bin -set MINGW_BIN=C:\MinGW\bin -set DCC= -set SUBDIR=gen-delphi -rem * CONFIGURATION END - - -REM ----------------------------------------------------- -:START -REM ----------------------------------------------------- - -rem * configured? -if "%SVNWORKDIR%"=="" goto CONFIG_ERROR - -rem * try to find dcc32.exe -echo Looking for dcc32.exe ... -if not exist "%DCC%" set DCC=%ProgramFiles%\Embarcadero\RAD Studio\8.0\bin\dcc32.exe -if not exist "%DCC%" set DCC=%ProgramFiles(x86)%\Embarcadero\RAD Studio\8.0\bin\dcc32.exe -if not exist "%DCC%" goto CONFIG_ERROR -echo Found %DCC% -echo. - -rem * some helpers -set PATH=%BIN%;%MINGW_BIN%;%PATH% -set TARGET=%SVNWORKDIR%\..\thrift-testing -set SOURCE=%SVNWORKDIR% -set TESTAPP=TestProject -set UNITSEARCH=%SOURCE%\lib\pas\src;%SOURCE%\lib\delphi\src -set OUTDCU="%TARGET%\dcu" -set LOGFILE=%TARGET%\%SUBDIR%\codegen.log - -rem * create and/or empty target dirs -if not exist "%TARGET%" md "%TARGET%" -if not exist "%TARGET%\%SUBDIR%" md "%TARGET%\%SUBDIR%" -if not exist "%OUTDCU%" md "%OUTDCU%" -if exist "%TARGET%\*.thrift" del "%TARGET%\*.thrift" /Q -if exist "%TARGET%\%SUBDIR%\*.*" del "%TARGET%\%SUBDIR%\*.*" /Q -if exist "%OUTDCU%\*.*" del "%OUTDCU%\*.*" /Q - -rem init logfile -echo Errors > "%LOGFILE%" -echo ---------------- >> "%LOGFILE%" - -rem * recurse through thrift WC and "my thrift files" folder -rem * copies all .thrift files into thrift-testing -call %0 %SOURCE% -if not "%MY_THRIFT_FILES%"=="" call %0 %MY_THRIFT_FILES% - -rem * compile all thrift files, generate PAS and C++ code -echo. -echo Generating code, please wait ... -cd "%TARGET%" -for %%a in (*.thrift) do "%BIN%\thrift.exe" -v --gen delphi:register_types,constprefix,events,xmldoc "%%a" 2>> "%LOGFILE%" -REM * for %%a in (*.thrift) do "%BIN%\thrift.exe" -v --gen cpp "%%a" >> NUL: -cmd /c start notepad "%LOGFILE%" -cd .. - -rem * check for special Delphi testcases being processed -if not exist "%TARGET%\%SUBDIR%\ReservedKeywords.pas" goto TESTCASE_MISSING - - -rem * generate a minimal DPR file that uses all generated pascal units -cd "%TARGET%\%SUBDIR%\" -if exist inherited.* ren inherited.* _inherited.* -echo program %TESTAPP%; > %TESTAPP%.dpr -echo {$APPTYPE CONSOLE} >> %TESTAPP%.dpr -echo. >> %TESTAPP%.dpr -echo uses >> %TESTAPP%.dpr -for %%a in (*.pas) do echo %%~na, >> %TESTAPP%.dpr -echo Windows, Classes, SysUtils; >> %TESTAPP%.dpr -echo. >> %TESTAPP%.dpr -echo begin >> %TESTAPP%.dpr -echo Writeln('Successfully compiled!'); >> %TESTAPP%.dpr -echo Writeln('List of units:'); >> %TESTAPP%.dpr -for %%a in (*.pas) do echo Write('%%~na':30,'':10); >> %TESTAPP%.dpr -echo Writeln; >> %TESTAPP%.dpr -echo end. >> %TESTAPP%.dpr -echo. >> %TESTAPP%.dpr -cd ..\.. - -rem * try to compile the DPR -rem * this should not throw any errors, warnings or hints -"%DCC%" -B "%TARGET%\%SUBDIR%\%TESTAPP%" -U"%UNITSEARCH%" -I"%UNITSEARCH%" -N"%OUTDCU%" -E"%TARGET%\%SUBDIR%" -dir "%TARGET%\%SUBDIR%\%TESTAPP%.exe" -if not exist "%TARGET%\%SUBDIR%\%TESTAPP%.exe" goto CODEGEN_FAILED -echo. -echo ----------------------------------------------------------------- -echo The compiled program is now executed. If it hangs or crashes, we -echo have a serious problem with the generated code. Expected output -echo is "Successfully compiled:" followed by a list of generated units. -echo ----------------------------------------------------------------- -"%TARGET%\%SUBDIR%\%TESTAPP%.exe" -echo ----------------------------------------------------------------- -echo. -pause -GOTO EOF - -REM ----------------------------------------------------- -:DXE_NOT_FOUND -REM ----------------------------------------------------- -echo Delphi Compiler (dcc32.exe) not found. -echo Please check the "DCC" setting in this batch. -echo. -cmd /c start notepad README.MD -cmd /c start notepad %0 -pause -GOTO EOF - - -REM ----------------------------------------------------- -:CONFIG_ERROR -REM ----------------------------------------------------- -echo Missing, incomplete or wrong configuration settings! -cmd /c start notepad README.MD -cmd /c start notepad %0 -pause -GOTO EOF - - -REM ----------------------------------------------------- -:TESTCASE_MISSING -REM ----------------------------------------------------- -echo Missing an expected Delphi testcase! -pause -GOTO EOF - - -REM ----------------------------------------------------- -:CODEGEN_FAILED -REM ----------------------------------------------------- -echo Code generation FAILED! -pause -GOTO EOF - - -REM ----------------------------------------------------- -:HANDLEDIR -REM ----------------------------------------------------- -REM echo %1 -for /D %%a in (%1\*) do call %0 %%a -if exist "%1\*.thrift" copy /b "%1\*.thrift" "%TARGET%\*.*" -GOTO EOF - - -REM ----------------------------------------------------- -:EOF -REM ----------------------------------------------------- diff --git a/lib/delphi/test/codegen/run-Pascal-Codegen-Tests.ps1 b/lib/delphi/test/codegen/run-Pascal-Codegen-Tests.ps1 new file mode 100644 index 00000000000..f02afba3625 --- /dev/null +++ b/lib/delphi/test/codegen/run-Pascal-Codegen-Tests.ps1 @@ -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. +# + +#---- failing tests -------------------------------------------- + +# expected to fail at Thrift Compiler +$FAIL_THRIFT = @( + "BrokenConstants.thrift", # intended to break + "DuplicateImportsTest.thrift", # subdir includes don't work here + "Include.thrift") # subdir includes don't work here + +# expected to fail at Delphi Compiler +$FAIL_DELPHI = @( + "Thrift5320.thrift" # this conflicts with Delphi scopes, but it's a bad practice testcase anyway +) + +# unexpected but known bugs (TODO: fix them) +$KNOWN_BUGS = @( + "IgnoreInitialismsTest.thrift", + "NameConflictTest.thrift" + ) + + + +#---- functions -------------------------------------------- + +function FindThriftExe() { + # prefer debug over release over path + write-host -nonewline Looking for thrift.exe ... + $exe = "thrift.exe" + + # if we have a freshly compiled one it might be a better choice + @("Release","Debug") | foreach{ + if( test-path "$ROOTDIR\compiler\cpp\$_\thrift.exe") { $exe = "$ROOTDIR\compiler\cpp\$_\thrift.exe" } + if( test-path "$ROOTDIR\compiler\cpp\compiler\$_\thrift.exe") { $exe = "$ROOTDIR\compiler\cpp\$_\compiler\thrift.exe" } + } + + return $exe +} + + +function FindDcc32Exe() { + # prefer debug over release over path + write-host -nonewline Looking for dcc32.exe ... + $exe = "dcc32.exe" + + # TODO: add arbitraily complex code to locate a suitable dcc32.exe if it is not in the path + + return $exe +} + + +function InitializeFolder([string] $folder, [string] $pattern) { + #write-host $folder\$pattern + if(-not (test-path $folder)) { + new-item $folder -type directory | out-null + } + pushd $folder + remove-item $pattern #-recurse + popd +} + + +function CopyFilesFrom([string] $source, $text) { + #write-host "$source" + if( ($source -ne "") -and (test-path $source)) { + if( $text -ne $null) { + write-host -foregroundcolor yellow Copying $text ... + } + + pushd $source + # recurse dirs + gci . -directory | foreach { + CopyFilesFrom "$_" + } + # files within + gci *.thrift -file | foreach { + #write-host $_ + $name = $_.name + copy-item $_ "$TARGET\$name" + } + popd + } +} + +function TestIdlFile([string] $idl) { + # expected to fail at Thrift Compiler + $filter = $false + $FAIL_THRIFT | foreach { + if( $idl -eq $_) { + $filter = $true + write-host "Skipping $_" + } + } + if( $filter) { return $true } + + # compile IDL + #write-host -nonewline " $idl" + InitializeFolder "$TARGET\gen-delphi" "*.pas" + &$THRIFT_EXE $VERBOSE -r --gen delphi:register_types,constprefix,events,xmldoc $idl | out-file "$TARGET\thrift.log" + if( -not $?) { + get-content "$TARGET\thrift.log" | out-default + write-host -foregroundcolor red "Thrift compilation failed: $idl" + return $false + } + + # generate project dile + $units = gci "$TARGET\gen-delphi\*.pas" + $lines = @() + $lines += "program $TESTAPP;" + $lines += "{`$APPTYPE CONSOLE}" + $lines += "" + $lines += "uses" + $units | foreach { $name = $_.name.Replace(".pas",""); $lines += " $name," } + $lines += " Windows, Classes, SysUtils;" + $lines += "" + $lines += "begin" + $lines += " Writeln('Successfully compiled!');" + $lines += " Writeln('List of units:');" + $units | foreach { $name = $_.name.Replace(".pas",""); $lines += " Writeln('- $name');" } + $lines += " Writeln;" + $lines += "" + $lines += "end." + $lines += "" + $lines | set-content "$TARGET\gen-delphi\$TESTAPP.dpr" + + # try to compile the DPR + # this should not throw any errors, warnings or hints + $exe = "$TARGET\gen-delphi\$TESTAPP.exe" + if( test-path $exe) { remove-item $exe } + &$DCC32_EXE -B "$TARGET\gen-delphi\$TESTAPP" -U"$UNITSEARCH" -I"$UNITSEARCH" -N"$OUTDCU" -E"$TARGET\gen-delphi" | out-file "$TARGET\compile.log" + if( -not (test-path $exe)) { + + # expected to fail at Thrift Compiler + $filter = $false + $FAIL_DELPHI | foreach { + if( $idl -eq $_) { + $filter = $true + write-host ("Delphi compilation failed at "+$idl+" - as expected") + } + } + $KNOWN_BUGS | foreach { + if( $idl -eq $_) { + $filter = $true + write-host ("Delphi compilation failed at "+$idl+" - known issue (TODO)") + } + } + if( $filter) { return $true } + + get-content "$TARGET\compile.log" | out-default + write-host -foregroundcolor red "Delphi compilation failed: $idl" + return $false + } + + # The compiled program is now executed. If it hangs or crashes, we + # have a serious problem with the generated code. Expected output + # is "Successfully compiled:" followed by a list of generated units. + &"$exe" | out-file "$TARGET\exec.log" + if( -not $?) { + get-content "$TARGET\exec.log" | out-default + write-host -foregroundcolor red "Test execution failed: $idl" + return $false + } + return $true +} + +#---- main ------------------------------------------------- +# CONFIGURATION BEGIN +# configuration settings, adjust as necessary to meet your system setup +$MY_THRIFT_FILES = "" +$VERBOSE = "" # set any Thrift compiler debug/verbose flag you want + +# init +$ROOTDIR = $PSScriptRoot + "\..\..\..\.." + +# try to find thrift.exe +$THRIFT_EXE = FindThriftExe +&$THRIFT_EXE -version +if( -not $?) { + write-host -foregroundcolor red Missing thrift.exe + exit 1 +} + +# try to find dcc32.exe +$DCC32_EXE = FindDcc32Exe +&$DCC32_EXE --version +if( -not $?) { + write-host -foregroundcolor red Missing dcc32.exe + exit 1 +} + + +# some helpers +$TARGET = "$ROOTDIR\..\thrift-testing" +$TESTAPP = "TestProject" +$UNITSEARCH = "$ROOTDIR\lib\pas\src;$ROOTDIR\lib\delphi\src" +$OUTDCU = "$TARGET\dcu" + +# create and/or empty target dirs +InitializeFolder "$TARGET" "*.thrift" +InitializeFolder "$TARGET\gen-delphi" "*.pas" +InitializeFolder "$OUTDCU" "*.dcu" + +# recurse through thrift WC and "my thrift files" folder +# copies all .thrift files into thrift-testing +CopyFilesFrom "$ROOTDIR" "Thrift IDL files" +CopyFilesFrom "$MY_THRIFT_FILES" "Custom IDL files" + +# codegen and compile all thrift files, one by one to prevent side effects +$count = 0 +write-host -foregroundcolor yellow Running codegen tests .. +try { + pushd "$TARGET" + gci *.thrift -file | foreach { + $count += 1 + $ok = TestIdlFile $_.name + if( -not $ok) { + throw "TEST FAILED" # automated tests + popd; pause; pushd "$TARGET" # interactive / debug + } + } + write-host -foregroundcolor green "Success ($count tests executed)" + exit 0 +} catch { + write-host -foregroundcolor red $_ + exit 1 +} finally { + popd +} + +#eof diff --git a/lib/delphi/test/serializer/SerializerData.dpr b/lib/delphi/test/serializer/SerializerData.dpr index 92ed00b0094..637e4ed9925 100644 --- a/lib/delphi/test/serializer/SerializerData.dpr +++ b/lib/delphi/test/serializer/SerializerData.dpr @@ -40,6 +40,8 @@ uses Thrift.TypeRegistry in '..\..\src\Thrift.TypeRegistry.pas', System_ in 'gen-delphi\System_.pas', SysUtils_ in 'gen-delphi\SysUtils_.pas', + test.ExceptionStruct in 'gen-delphi\test.ExceptionStruct.pas', + test.SimpleException in 'gen-delphi\test.SimpleException.pas', DebugProtoTest in 'gen-delphi\DebugProtoTest.pas', TestSerializer.Data in 'TestSerializer.Data.pas'; @@ -69,11 +71,26 @@ begin end; +function CreateBatchGetResponse : IBatchGetResponse; stdcall; +begin + result := Fixtures.CreateBatchGetResponse; +end; + + +function CreateSimpleException : IError; stdcall; +begin + result := Fixtures.CreateSimpleException; +end; + + exports CreateOneOfEach, CreateNesting, CreateHolyMoley, - CreateCompactProtoTestStruct; + CreateCompactProtoTestStruct, + CreateBatchGetResponse, + CreateSimpleException; + begin IsMultiThread := TRUE; diff --git a/lib/delphi/test/serializer/SerializerData.dproj b/lib/delphi/test/serializer/SerializerData.dproj index cfc27f8781d..ac744c143a1 100644 --- a/lib/delphi/test/serializer/SerializerData.dproj +++ b/lib/delphi/test/serializer/SerializerData.dproj @@ -85,6 +85,8 @@ + + @@ -100,10 +102,12 @@ - + - + Delphi.Personality.12 @@ -140,6 +144,9 @@ thrift.exe -r -gen delphi:com_types ..\..\..\..\test\DebugProtoTest.thrift]]>

SerializerData.dpr + + bin\Debug\Win32\TestSerializer.exe + True diff --git a/lib/delphi/test/serializer/SimpleException.thrift b/lib/delphi/test/serializer/SimpleException.thrift new file mode 100644 index 00000000000..c13876c8d74 --- /dev/null +++ b/lib/delphi/test/serializer/SimpleException.thrift @@ -0,0 +1,32 @@ +/* + * 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 * test.SimpleException + +exception Error { + 1: i32 ErrorCode = 42 + /** test name collision with Exception class */ + 2: Error InnerException + /** test name collisions with Thrift Delphi implementation details */ + 3: uuid ExceptionData = '00000000-4444-CCCC-ffff-0123456789ab' +} + + + +// EOF diff --git a/lib/delphi/test/serializer/TestSerializer.Data.pas b/lib/delphi/test/serializer/TestSerializer.Data.pas index 24f850d2f61..ddf4ba243eb 100644 --- a/lib/delphi/test/serializer/TestSerializer.Data.pas +++ b/lib/delphi/test/serializer/TestSerializer.Data.pas @@ -27,6 +27,8 @@ interface ComObj, Thrift.Protocol, Thrift.Collections, + test.ExceptionStruct, + test.SimpleException, DebugProtoTest; @@ -37,6 +39,8 @@ Fixtures = class class function CreateNesting : INesting; class function CreateHolyMoley : IHolyMoley; class function CreateCompactProtoTestStruct : ICompactProtoTestStruct; + class function CreateBatchGetResponse : IBatchGetResponse; + class function CreateSimpleException : IError; // These byte arrays are serialized versions of the above structs. // They were serialized in binary protocol using thrift 0.6.x and are used to @@ -359,6 +363,51 @@ class function Fixtures.CreateCompactProtoTestStruct : ICompactProtoTestStruct; end; +class function Fixtures.CreateBatchGetResponse : IBatchGetResponse; +var + data : IGetRequest; + error : ISomeException; +const + REQUEST_ID = '123'; +begin + data := TGetRequestImpl.Create; + data.Id := REQUEST_ID; + data.Data := TThriftBytesImpl.Create( TEncoding.UTF8.GetBytes( #0#1#2#3#4#5#6#7#8)); + + error := TSomeExceptionImpl.Create; + error.Error := TErrorCode.GenericError; + + result := TBatchGetResponseImpl.Create; + result.Responses := TThriftDictionaryImpl.Create; + result.Responses.Add( REQUEST_ID, data); + result.Errors := TThriftDictionaryImpl.Create; + result.Errors.Add( REQUEST_ID, error); +end; + + +class function Fixtures.CreateSimpleException : IError; +var i : Integer; + inner : IError; + guid : TGuid; +const + IDL_GUID_VALUE : TGuid = '{00000000-4444-CCCC-ffff-0123456789ab}'; +begin + result := nil; + for i := 0 to 4 do begin + inner := result; + result := TErrorImpl.Create; + + // validate const values set in IDL + ASSERT( result.ErrorCode = 42); // IDL default value + ASSERT( IsEqualGUID( result.ExceptionData, IDL_GUID_VALUE)); + + // set fresh, but reproducible values + FillChar( guid, SizeOf(guid), i); + result.ErrorCode := i; + result.ExceptionData := guid; + result.InnerException := inner; + end; +end; end. diff --git a/lib/delphi/test/serializer/TestSerializer.Tests.pas b/lib/delphi/test/serializer/TestSerializer.Tests.pas index 6ed1a48a2c5..466fb269efc 100644 --- a/lib/delphi/test/serializer/TestSerializer.Tests.pas +++ b/lib/delphi/test/serializer/TestSerializer.Tests.pas @@ -41,6 +41,8 @@ interface Thrift.WinHTTP, Thrift.TypeRegistry, System_, + test.ExceptionStruct, + test.SimpleException, DebugProtoTest; {$TYPEINFO ON} @@ -81,8 +83,12 @@ TTestSerializer = class //extends TestCase { procedure Test_Serializer_Deserializer; procedure Test_COM_Types; - procedure Test_OneOfEach( const method : TMethod; const factory : TFactoryPair; const stream : TFileStream); - procedure Test_CompactStruct( const method : TMethod; const factory : TFactoryPair; const stream : TFileStream); + procedure Test_ThriftBytesCTORs; + + procedure Test_OneOfEach( const method : TMethod; const factory : TFactoryPair; const stream : TFileStream); + procedure Test_CompactStruct( const method : TMethod; const factory : TFactoryPair; const stream : TFileStream); + procedure Test_ExceptionStruct( const method : TMethod; const factory : TFactoryPair; const stream : TFileStream); + procedure Test_SimpleException( const method : TMethod; const factory : TFactoryPair; const stream : TFileStream); public constructor Create; @@ -99,6 +105,8 @@ function CreateOneOfEach : IOneOfEach; stdcall; external SERIALIZERDATA_DLL; function CreateNesting : INesting; stdcall; external SERIALIZERDATA_DLL; function CreateHolyMoley : IHolyMoley; stdcall; external SERIALIZERDATA_DLL; function CreateCompactProtoTestStruct : ICompactProtoTestStruct; stdcall; external SERIALIZERDATA_DLL; +function CreateBatchGetResponse : IBatchGetResponse; stdcall; external SERIALIZERDATA_DLL; +function CreateSimpleException : IError; stdcall; external SERIALIZERDATA_DLL; { TTestSerializer } @@ -265,6 +273,105 @@ procedure TTestSerializer.Test_CompactStruct( const method : TMethod; const fact end; +procedure TTestSerializer.Test_ExceptionStruct( const method : TMethod; const factory : TFactoryPair; const stream : TFileStream); +var tested, correct : IBatchGetResponse; + bytes : TBytes; + corrDP, testDP : TPair; + corrEP, testEP : TPair; +begin + // write + tested := CreateBatchGetResponse; + case method of + mt_Bytes: bytes := Serialize( tested, factory); + mt_Stream: begin + stream.Size := 0; + Serialize( tested, factory, stream); + end + else + ASSERT( FALSE); + end; + + // init + read + correct := TBatchGetResponseImpl.Create; + case method of + mt_Bytes: Deserialize( bytes, tested, factory); + mt_Stream: begin + stream.Position := 0; + Deserialize( stream, tested, factory); + end + else + ASSERT( FALSE); + end; + + // check + correct := CreateBatchGetResponse; + + // rewrite the following test if not + ASSERT( tested.Responses.Count = 1); + ASSERT( correct.Responses.Count = tested.Responses.Count); + for corrDP in correct.Responses do begin + for testDP in tested.Responses do begin + ASSERT( corrDP.Key = testDP.Key); + ASSERT( corrDP.Value.Id = testDP.Value.Id); + ASSERT( corrDP.Value.Data.Count = testDP.Value.Data.Count); + end; + end; + + // rewrite the following test if not + ASSERT( tested.Errors.Count = 1); + ASSERT( correct.Errors.Count = tested.Errors.Count); + for corrEP in correct.Errors do begin + for testEP in tested.Errors do begin + ASSERT( corrEP.Key = testEP.Key); + ASSERT( corrEP.Value.Error = testEP.Value.Error); + end; + end; +end; + + +procedure TTestSerializer.Test_SimpleException( const method : TMethod; const factory : TFactoryPair; const stream : TFileStream); +var tested, correct : IError; + bytes : TBytes; +begin + // write + tested := CreateSimpleException; + case method of + mt_Bytes: bytes := Serialize( tested, factory); + mt_Stream: begin + stream.Size := 0; + Serialize( tested, factory, stream); + end + else + ASSERT( FALSE); + end; + + // init + read + correct := TErrorImpl.Create; + case method of + mt_Bytes: Deserialize( bytes, tested, factory); + mt_Stream: begin + stream.Position := 0; + Deserialize( stream, tested, factory); + end + else + ASSERT( FALSE); + end; + + // check + correct := CreateSimpleException; + while correct <> nil do begin + // validate + ASSERT( correct.ErrorCode = tested.ErrorCode); + ASSERT( IsEqualGUID( correct.ExceptionData, tested.ExceptionData)); + + // iterate + correct := correct.InnerException; + tested := tested.InnerException; + ASSERT( (tested <> nil) xor (correct = nil)); // both or none + end; +end; + + procedure TTestSerializer.Test_Serializer_Deserializer; var factory : TFactoryPair; stream : TFileStream; @@ -278,8 +385,10 @@ procedure TTestSerializer.Test_Serializer_Deserializer; for factory in FProtocols do begin Writeln('- '+UserFriendlyName(factory)); - Test_OneOfEach( method, factory, stream); - Test_CompactStruct( method, factory, stream); + Test_OneOfEach( method, factory, stream); + Test_CompactStruct( method, factory, stream); + Test_ExceptionStruct( method, factory, stream); + Test_SimpleException( method, factory, stream); end; Writeln; @@ -325,11 +434,28 @@ procedure TTestSerializer.Test_COM_Types; end; +procedure TTestSerializer.Test_ThriftBytesCTORs; +var one, two : IThriftBytes; + bytes : TBytes; + sAscii : AnsiString; +begin + sAscii := 'ABC/xzy'; + bytes := TEncoding.ASCII.GetBytes(string(sAscii)); + + one := TThriftBytesImpl.Create( PAnsiChar(sAscii), Length(sAscii)); + two := TThriftBytesImpl.Create( bytes, TRUE); + + ASSERT( one.Count = two.Count); + ASSERT( CompareMem( one.QueryRawDataPtr, two.QueryRawDataPtr, one.Count)); +end; + + procedure TTestSerializer.RunTests; begin try Test_Serializer_Deserializer; Test_COM_Types; + Test_ThriftBytesCTORs; except on e:Exception do begin Writeln( e.ClassName+': '+ e.Message); diff --git a/lib/delphi/test/serializer/TestSerializer.dpr b/lib/delphi/test/serializer/TestSerializer.dpr index b78c0db05d9..8c2f64d9e10 100644 --- a/lib/delphi/test/serializer/TestSerializer.dpr +++ b/lib/delphi/test/serializer/TestSerializer.dpr @@ -44,6 +44,8 @@ uses System_ in 'gen-delphi\System_.pas', SysUtils_ in 'gen-delphi\SysUtils_.pas', DebugProtoTest in 'gen-delphi\DebugProtoTest.pas', + test.ExceptionStruct in 'gen-delphi\test.ExceptionStruct.pas', + test.SimpleException in 'gen-delphi\test.SimpleException.pas', TestSerializer.Tests in 'TestSerializer.Tests.pas'; diff --git a/lib/delphi/test/serializer/TestSerializer.dproj b/lib/delphi/test/serializer/TestSerializer.dproj index 383e04a9547..1e348d5a89c 100644 --- a/lib/delphi/test/serializer/TestSerializer.dproj +++ b/lib/delphi/test/serializer/TestSerializer.dproj @@ -85,6 +85,8 @@ + + Cfg_2 @@ -99,10 +101,12 @@ - + +thrift.exe -r -gen delphi:com_types ..\..\..\..\test\DebugProtoTest.thrift +thrift.exe -r -gen delphi:com_types ..\..\..\..\test\ExceptionStruct.thrift +thrift.exe -r -gen delphi:com_types SimpleException.thrift]]> Delphi.Personality.12 diff --git a/lib/delphi/test/server.dpr b/lib/delphi/test/server.dpr index 79942816980..0cab02f3395 100644 --- a/lib/delphi/test/server.dpr +++ b/lib/delphi/test/server.dpr @@ -23,8 +23,9 @@ program server; uses SysUtils, - TestServer in 'TestServer.pas', - TestServerEvents in 'TestServerEvents.pas', + TestConstants in 'testsuite\TestConstants.pas', + TestServer in 'testsuite\server\TestServer.pas', + TestServerEvents in 'testsuite\server\TestServerEvents.pas', Thrift.Test in 'gen-delphi\Thrift.Test.pas', Thrift in '..\src\Thrift.pas', Thrift.Exception in '..\src\Thrift.Exception.pas', diff --git a/lib/delphi/test/server.dproj b/lib/delphi/test/server.dproj index 8e9b99dd72d..37ef9c9a6ed 100644 --- a/lib/delphi/test/server.dproj +++ b/lib/delphi/test/server.dproj @@ -50,8 +50,9 @@ MainSource - - + + + diff --git a/lib/delphi/test/TestConstants.pas b/lib/delphi/test/testsuite/TestConstants.pas similarity index 85% rename from lib/delphi/test/TestConstants.pas rename to lib/delphi/test/testsuite/TestConstants.pas index 9ac4808c056..e51b60084b9 100644 --- a/lib/delphi/test/TestConstants.pas +++ b/lib/delphi/test/testsuite/TestConstants.pas @@ -55,6 +55,18 @@ interface TLayeredTransports = set of TLayeredTransport; + {$SCOPEDENUMS ON} + TTestSize = ( + Empty, // Edge case: the zero-length empty binary + Normal, // Fairly small array of usual size (256 bytes) + ByteArrayTest, // THRIFT-4454 Large writes/reads may cause range check errors in debug mode + PipeWriteLimit, // THRIFT-4372 Pipe write operations across a network are limited to 65,535 bytes per write. + FifteenMB // quite a bit of data, but still below the default max frame size + ); + {$SCOPEDENUMS OFF} + + + const PROTOCOL_CLASSES : array[TKnownProtocol] of TProtocolImplClass = ( TBinaryProtocolImpl, @@ -151,6 +163,8 @@ interface function BytesToHex( const bytes : TBytes) : string; +function PrepareBinaryData( aRandomDist : Boolean; aSize : TTestSize) : TBytes; + implementation @@ -165,4 +179,38 @@ function BytesToHex( const bytes : TBytes) : string; end; +function PrepareBinaryData( aRandomDist : Boolean; aSize : TTestSize) : TBytes; +var i : Integer; +begin + case aSize of + TTestSize.Empty : SetLength( result, 0); + TTestSize.Normal : SetLength( result, $100); + TTestSize.ByteArrayTest : SetLength( result, SizeOf(TByteArray) + 128); + TTestSize.PipeWriteLimit : SetLength( result, 65535 + 128); + TTestSize.FifteenMB : SetLength( result, 15 * 1024 * 1024); + else + raise EArgumentException.Create('aSize'); + end; + + ASSERT( Low(result) = 0); + if Length(result) = 0 then Exit; + + // linear distribution, unless random is requested + if not aRandomDist then begin + for i := Low(result) to High(result) do begin + result[i] := i mod $100; + end; + Exit; + end; + + // random distribution of all 256 values + FillChar( result[0], Length(result) * SizeOf(result[0]), $0); + for i := Low(result) to High(result) do begin + result[i] := Byte( Random($100)); + end; +end; + + + + end. diff --git a/lib/delphi/test/Performance/DataFactory.pas b/lib/delphi/test/testsuite/client/Performance/DataFactory.pas similarity index 100% rename from lib/delphi/test/Performance/DataFactory.pas rename to lib/delphi/test/testsuite/client/Performance/DataFactory.pas diff --git a/lib/delphi/test/Performance/PerfTests.pas b/lib/delphi/test/testsuite/client/Performance/PerfTests.pas similarity index 100% rename from lib/delphi/test/Performance/PerfTests.pas rename to lib/delphi/test/testsuite/client/Performance/PerfTests.pas diff --git a/lib/delphi/test/TestClient.pas b/lib/delphi/test/testsuite/client/TestClient.pas similarity index 80% rename from lib/delphi/test/TestClient.pas rename to lib/delphi/test/testsuite/client/TestClient.pas index 1b09d3cf450..aca64410c17 100644 --- a/lib/delphi/test/TestClient.pas +++ b/lib/delphi/test/testsuite/client/TestClient.pas @@ -39,8 +39,10 @@ interface DateUtils, Generics.Collections, TestConstants, + TestLogger, ConsoleHelper, PerfTests, + UnitTests, Thrift, Thrift.Protocol.Compact, Thrift.Protocol.JSON, @@ -82,25 +84,6 @@ TTestSetup = record end; TClientThread = class( TThread ) - private type - TTestGroup = ( - test_Unknown, - test_BaseTypes, - test_Structs, - test_Containers, - test_Exceptions - // new values here - ); - TTestGroups = set of TTestGroup; - - TTestSize = ( - Empty, // Edge case: the zero-length empty binary - Normal, // Fairly small array of usual size (256 bytes) - ByteArrayTest, // THRIFT-4454 Large writes/reads may cause range check errors in debug mode - PipeWriteLimit, // THRIFT-4372 Pipe write operations across a network are limited to 65,535 bytes per write. - FifteenMB // quite a bit of data, but still below the default max frame size - ); - strict private FSetup : TTestSetup; FTransport : ITransport; @@ -109,18 +92,7 @@ TClientThread = class( TThread ) FThreadNo : Integer; FConsole : TThreadConsole; - - // test reporting, will be refactored out into separate class later - FTestGroup : string; - FCurrentTest : TTestGroup; - FSuccesses : Integer; - FErrors : TStringList; - FFailed : TTestGroups; - FExecuted : TTestGroups; - procedure StartTestGroup( const aGroup : string; const aTest : TTestGroup); - procedure Expect( aTestResult : Boolean; const aTestInfo : string); - procedure ReportResults; - function CalculateExitCode : Byte; + FLogger : ITestLogger; procedure ClientTest; {$IFDEF SupportsAsync} @@ -131,14 +103,13 @@ TClientThread = class( TThread ) procedure ShutdownProtocolTransportStack; function InitializeHttpTransport( const aTimeoutSetting : Integer; const aConfig : IThriftConfiguration = nil) : IHTTPClient; - procedure JSONProtocolReadWriteTest; - function PrepareBinaryData( aRandomDist : Boolean; aSize : TTestSize) : TBytes; {$IFDEF StressTest} procedure StressTest(const client : TThriftTest.Iface); {$ENDIF} - {$IFDEF Win64} - procedure UseInterlockedExchangeAdd64; - {$ENDIF} + + procedure StartTestGroup( const aGroup : string; const aTest : TClientTestGroup); inline; + procedure Expect( aTestResult : Boolean; const aTestInfo : string); inline; + function CalculateExitCode : Byte; strict protected procedure Execute; override; @@ -174,7 +145,7 @@ implementation EXITCODE_FAILBIT_CONTAINERS = $04; EXITCODE_FAILBIT_EXCEPTIONS = $08; - MAP_FAILURES_TO_EXITCODE_BITS : array[TClientThread.TTestGroup] of Byte = ( + MAP_FAILURES_TO_EXITCODE_BITS : array[TClientTestGroup] of Byte = ( EXITCODE_SUCCESS, // no bits here EXITCODE_FAILBIT_BASETYPES, EXITCODE_FAILBIT_STRUCTS, @@ -1052,260 +1023,26 @@ procedure TClientThread.StressTest(const client : TThriftTest.Iface); {$ENDIF} -function TClientThread.PrepareBinaryData( aRandomDist : Boolean; aSize : TTestSize) : TBytes; -var i : Integer; +procedure TClientThread.StartTestGroup( const aGroup : string; const aTest : TClientTestGroup); begin - case aSize of - Empty : SetLength( result, 0); - Normal : SetLength( result, $100); - ByteArrayTest : SetLength( result, SizeOf(TByteArray) + 128); - PipeWriteLimit : SetLength( result, 65535 + 128); - FifteenMB : SetLength( result, 15 * 1024 * 1024); - else - raise EArgumentException.Create('aSize'); - end; - - ASSERT( Low(result) = 0); - if Length(result) = 0 then Exit; - - // linear distribution, unless random is requested - if not aRandomDist then begin - for i := Low(result) to High(result) do begin - result[i] := i mod $100; - end; - Exit; - end; - - // random distribution of all 256 values - FillChar( result[0], Length(result) * SizeOf(result[0]), $0); - for i := Low(result) to High(result) do begin - result[i] := Byte( Random($100)); - end; -end; - - -{$IFDEF Win64} -procedure TClientThread.UseInterlockedExchangeAdd64; -var a,b : Int64; -begin - a := 1; - b := 2; - Thrift.Utils.InterlockedExchangeAdd64( a,b); - Expect( a = 3, 'InterlockedExchangeAdd64'); -end; -{$ENDIF} - - -procedure TClientThread.JSONProtocolReadWriteTest; -// Tests only then read/write procedures of the JSON protocol -// All tests succeed, if we can read what we wrote before -// Note that passing this test does not imply, that our JSON is really compatible to what -// other clients or servers expect as the real JSON. This is beyond the scope of this test. -var prot : IProtocol; - stm : TStringStream; - list : TThriftList; - config : IThriftConfiguration; - binary, binRead, emptyBinary : TBytes; - i,iErr : Integer; -const - TEST_SHORT = ShortInt( $FE); - TEST_SMALL = SmallInt( $FEDC); - TEST_LONG = LongInt( $FEDCBA98); - TEST_I64 = Int64( $FEDCBA9876543210); - TEST_DOUBLE = -1.234e-56; - DELTA_DOUBLE = TEST_DOUBLE * 1e-14; - TEST_STRING = 'abc-'#$00E4#$00f6#$00fc; // german umlauts (en-us: "funny chars") - // Test THRIFT-2336 and THRIFT-3404 with U+1D11E (G Clef symbol) and 'Русское Название'; - G_CLEF_AND_CYRILLIC_TEXT = #$1d11e' '#$0420#$0443#$0441#$0441#$043a#$043e#$0435' '#$041d#$0430#$0437#$0432#$0430#$043d#$0438#$0435; - G_CLEF_AND_CYRILLIC_JSON = '"\ud834\udd1e \u0420\u0443\u0441\u0441\u043a\u043e\u0435 \u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435"'; - // test both possible solidus encodings - SOLIDUS_JSON_DATA = '"one/two\/three"'; - SOLIDUS_EXCPECTED = 'one/two/three'; -begin - stm := TStringStream.Create; - try - StartTestGroup( 'JsonProtocolTest', test_Unknown); - - config := TThriftConfigurationImpl.Create; - - // prepare binary data - binary := PrepareBinaryData( FALSE, Normal); - SetLength( emptyBinary, 0); // empty binary data block - - // output setup - prot := TJSONProtocolImpl.Create( - TStreamTransportImpl.Create( - nil, TThriftStreamAdapterDelphi.Create( stm, FALSE), config)); - - // write - Init( list, TType.String_, 9); - prot.WriteListBegin( list); - prot.WriteBool( TRUE); - prot.WriteBool( FALSE); - prot.WriteByte( TEST_SHORT); - prot.WriteI16( TEST_SMALL); - prot.WriteI32( TEST_LONG); - prot.WriteI64( TEST_I64); - prot.WriteDouble( TEST_DOUBLE); - prot.WriteString( TEST_STRING); - prot.WriteBinary( binary); - prot.WriteString( ''); // empty string - prot.WriteBinary( emptyBinary); // empty binary data block - prot.WriteListEnd; - - // input setup - Expect( stm.Position = stm.Size, 'Stream position/length after write'); - stm.Position := 0; - prot := TJSONProtocolImpl.Create( - TStreamTransportImpl.Create( - TThriftStreamAdapterDelphi.Create( stm, FALSE), nil, config)); - - // read and compare - list := prot.ReadListBegin; - Expect( list.ElementType = TType.String_, 'list element type'); - Expect( list.Count = 9, 'list element count'); - Expect( prot.ReadBool, 'WriteBool/ReadBool: TRUE'); - Expect( not prot.ReadBool, 'WriteBool/ReadBool: FALSE'); - Expect( prot.ReadByte = TEST_SHORT, 'WriteByte/ReadByte'); - Expect( prot.ReadI16 = TEST_SMALL, 'WriteI16/ReadI16'); - Expect( prot.ReadI32 = TEST_LONG, 'WriteI32/ReadI32'); - Expect( prot.ReadI64 = TEST_I64, 'WriteI64/ReadI64'); - Expect( abs(prot.ReadDouble-TEST_DOUBLE) < abs(DELTA_DOUBLE), 'WriteDouble/ReadDouble'); - Expect( prot.ReadString = TEST_STRING, 'WriteString/ReadString'); - binRead := prot.ReadBinary; - Expect( Length(prot.ReadString) = 0, 'WriteString/ReadString (empty string)'); - Expect( Length(prot.ReadBinary) = 0, 'empty WriteBinary/ReadBinary (empty data block)'); - prot.ReadListEnd; - - // test binary data - Expect( Length(binary) = Length(binRead), 'Binary data length check'); - iErr := -1; - for i := Low(binary) to High(binary) do begin - if binary[i] <> binRead[i] then begin - iErr := i; - Break; - end; - end; - if iErr < 0 - then Expect( TRUE, 'Binary data check ('+IntToStr(Length(binary))+' Bytes)') - else Expect( FALSE, 'Binary data check at offset '+IntToStr(iErr)); - - Expect( stm.Position = stm.Size, 'Stream position after read'); - - - // Solidus can be encoded in two ways. Make sure we can read both - stm.Position := 0; - stm.Size := 0; - stm.WriteString(SOLIDUS_JSON_DATA); - stm.Position := 0; - prot := TJSONProtocolImpl.Create( - TStreamTransportImpl.Create( - TThriftStreamAdapterDelphi.Create( stm, FALSE), nil, config)); - Expect( prot.ReadString = SOLIDUS_EXCPECTED, 'Solidus encoding'); - - - // Widechars should work too. Do they? - // After writing, we ensure that we are able to read it back - // We can't assume hex-encoding, since (nearly) any Unicode char is valid JSON - stm.Position := 0; - stm.Size := 0; - prot := TJSONProtocolImpl.Create( - TStreamTransportImpl.Create( - nil, TThriftStreamAdapterDelphi.Create( stm, FALSE), config)); - prot.WriteString( G_CLEF_AND_CYRILLIC_TEXT); - stm.Position := 0; - prot := TJSONProtocolImpl.Create( - TStreamTransportImpl.Create( - TThriftStreamAdapterDelphi.Create( stm, FALSE), nil, config)); - Expect( prot.ReadString = G_CLEF_AND_CYRILLIC_TEXT, 'Writing JSON with chars > 8 bit'); - - // Widechars should work with hex-encoding too. Do they? - stm.Position := 0; - stm.Size := 0; - stm.WriteString( G_CLEF_AND_CYRILLIC_JSON); - stm.Position := 0; - prot := TJSONProtocolImpl.Create( - TStreamTransportImpl.Create( - TThriftStreamAdapterDelphi.Create( stm, FALSE), nil, config)); - Expect( prot.ReadString = G_CLEF_AND_CYRILLIC_TEXT, 'Reading JSON with chars > 8 bit'); - - - finally - stm.Free; - prot := nil; //-> Release - StartTestGroup( '', test_Unknown); // no more tests here - end; -end; - - -procedure TClientThread.StartTestGroup( const aGroup : string; const aTest : TTestGroup); -begin - FTestGroup := aGroup; - FCurrentTest := aTest; - - Include( FExecuted, aTest); - - if FTestGroup <> '' then begin - Console.WriteLine(''); - Console.WriteLine( aGroup+' tests'); - Console.WriteLine( StringOfChar('-',60)); - end; + FLogger.StartTestGroup( aGroup, aTest); end; procedure TClientThread.Expect( aTestResult : Boolean; const aTestInfo : string); begin - if aTestResult then begin - Inc(FSuccesses); - Console.WriteLine( aTestInfo+': passed'); - end - else begin - FErrors.Add( FTestGroup+': '+aTestInfo); - Include( FFailed, FCurrentTest); - Console.WriteLine( aTestInfo+': *** FAILED ***'); - - // We have a failed test! - // -> issue DebugBreak ONLY if a debugger is attached, - // -> unhandled DebugBreaks would cause Windows to terminate the app otherwise - if IsDebuggerPresent - then {$IFDEF CPUX64} DebugBreak {$ELSE} asm int 3 end {$ENDIF}; - end; -end; - - -procedure TClientThread.ReportResults; -var nTotal : Integer; - sLine : string; -begin - // prevent us from stupid DIV/0 errors - nTotal := FSuccesses + FErrors.Count; - if nTotal = 0 then begin - Console.WriteLine('No results logged'); - Exit; - end; - - Console.WriteLine(''); - Console.WriteLine( StringOfChar('=',60)); - Console.WriteLine( IntToStr(nTotal)+' tests performed'); - Console.WriteLine( IntToStr(FSuccesses)+' tests succeeded ('+IntToStr(round(100*FSuccesses/nTotal))+'%)'); - Console.WriteLine( IntToStr(FErrors.Count)+' tests failed ('+IntToStr(round(100*FErrors.Count/nTotal))+'%)'); - Console.WriteLine( StringOfChar('=',60)); - if FErrors.Count > 0 then begin - Console.WriteLine('FAILED TESTS:'); - for sLine in FErrors do Console.WriteLine('- '+sLine); - Console.WriteLine( StringOfChar('=',60)); - InterlockedIncrement( ExitCode); // return <> 0 on errors - end; - Console.WriteLine(''); + FLogger.Expect( aTestResult, aTestInfo); end; function TClientThread.CalculateExitCode : Byte; -var test : TTestGroup; +var test : TClientTestGroup; + failed, executed : TClientTestGroups; begin result := EXITCODE_SUCCESS; - for test := Low(TTestGroup) to High(TTestGroup) do begin - if (test in FFailed) or not (test in FExecuted) + FLogger.QueryTestStats( failed, executed); + for test := Low(TClientTestGroup) to High(TClientTestGroup) do begin + if (test in failed) or not (test in executed) then result := result or MAP_FAILURES_TO_EXITCODE_BITS[test]; end; end; @@ -1318,12 +1055,7 @@ constructor TClientThread.Create( const aSetup : TTestSetup; const aNumIteration FNumIterations := aNumIteration; FConsole := TThreadConsole.Create( Self, aLogThreadID); - FCurrentTest := test_Unknown; - - // error list: keep correct order, allow for duplicates - FErrors := TStringList.Create; - FErrors.Sorted := FALSE; - FErrors.Duplicates := dupAccept; + FLogger := TTestLoggerImpl.Create; inherited Create( TRUE); end; @@ -1331,7 +1063,7 @@ constructor TClientThread.Create( const aSetup : TTestSetup; const aNumIteration destructor TClientThread.Destroy; begin FreeAndNil( FConsole); - FreeAndNil( FErrors); + FLogger := nil; //-> Release inherited; end; @@ -1341,10 +1073,9 @@ procedure TClientThread.Execute; begin // perform all tests try - {$IFDEF Win64} - UseInterlockedExchangeAdd64; - {$ENDIF} - JSONProtocolReadWriteTest; + // builtin (quick) unit tests on one thread only + if ThreadNo = 0 + then TQuickUnitTests.Execute(FLogger); // must be run in the context of the thread InitializeProtocolTransportStack; @@ -1357,7 +1088,7 @@ procedure TClientThread.Execute; end; // report the outcome - ReportResults; + FLogger.ReportResults; SetReturnValue( CalculateExitCode); finally diff --git a/lib/delphi/test/testsuite/client/TestLogger.pas b/lib/delphi/test/testsuite/client/TestLogger.pas new file mode 100644 index 00000000000..10ddfc74c1a --- /dev/null +++ b/lib/delphi/test/testsuite/client/TestLogger.pas @@ -0,0 +1,193 @@ +(* + * 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 TestLogger; + +{$I ../src/Thrift.Defines.inc} + +interface + +uses + Classes, Windows, SysUtils, Math, ActiveX, ComObj, + {$IFDEF SupportsAsync} System.Threading, {$ENDIF} + DateUtils, + Generics.Collections, + TestConstants, + ConsoleHelper, + Thrift, + Thrift.Protocol.Compact, + Thrift.Protocol.JSON, + Thrift.Protocol, + Thrift.Transport.Pipes, + Thrift.Transport.WinHTTP, + Thrift.Transport.MsxmlHTTP, + Thrift.Transport, + Thrift.Stream, + Thrift.Test, + Thrift.WinHTTP, + Thrift.Utils, + Thrift.Configuration, + Thrift.Collections; + + +type + TClientTestGroup = ( + test_Unknown, + test_BaseTypes, + test_Structs, + test_Containers, + test_Exceptions + // new values here + ); + TClientTestGroups = set of TClientTestGroup; + + + ITestLogger = interface + ['{26693ED5-1469-48AD-B1F3-04281B053DD4}'] + procedure StartTestGroup( const aGroup : string; const aTest : TClientTestGroup); + procedure Expect( aTestResult : Boolean; const aTestInfo : string); + procedure QueryTestStats( out failed, executed : TClientTestGroups); + procedure ReportResults; + end; + + + // test reporting helper + TTestLoggerImpl = class( TInterfacedObject, ITestLogger) + strict private + FTestGroup : string; + FCurrentTest : TClientTestGroup; + FSuccesses : Integer; + FErrors : TStringList; + FFailed : TClientTestGroups; + FExecuted : TClientTestGroups; + + strict protected + // ITestLogger = interface + procedure StartTestGroup( const aGroup : string; const aTest : TClientTestGroup); + procedure Expect( aTestResult : Boolean; const aTestInfo : string); + procedure QueryTestStats( out failed, executed : TClientTestGroups); + procedure ReportResults; + + public + constructor Create; + destructor Destroy; override; + + end; + + +implementation + + +constructor TTestLoggerImpl.Create; +begin + inherited Create; + FCurrentTest := test_Unknown; + + // error list: keep correct order, allow for duplicates + FErrors := TStringList.Create; + FErrors.Sorted := FALSE; + FErrors.Duplicates := dupAccept; +end; + + +destructor TTestLoggerImpl.Destroy; +begin + try + FreeAndNil( FErrors); + finally + inherited Destroy; + end; +end; + + +procedure TTestLoggerImpl.StartTestGroup( const aGroup : string; const aTest : TClientTestGroup); +begin + FTestGroup := aGroup; + FCurrentTest := aTest; + + Include( FExecuted, aTest); + + if FTestGroup <> '' then begin + Console.WriteLine(''); + Console.WriteLine( aGroup+' tests'); + Console.WriteLine( StringOfChar('-',60)); + end; +end; + + +procedure TTestLoggerImpl.Expect( aTestResult : Boolean; const aTestInfo : string); +begin + if aTestResult then begin + Inc(FSuccesses); + Console.WriteLine( aTestInfo+': passed'); + end + else begin + FErrors.Add( FTestGroup+': '+aTestInfo); + Include( FFailed, FCurrentTest); + Console.WriteLine( aTestInfo+': *** FAILED ***'); + + // We have a failed test! + // -> issue DebugBreak ONLY if a debugger is attached, + // -> unhandled DebugBreaks would cause Windows to terminate the app otherwise + if IsDebuggerPresent + then {$IFDEF CPUX64} DebugBreak {$ELSE} asm int 3 end {$ENDIF}; + end; +end; + + +procedure TTestLoggerImpl.QueryTestStats( out failed, executed : TClientTestGroups); +begin + failed := FFailed; + executed := FExecuted; +end; + + + +procedure TTestLoggerImpl.ReportResults; +var nTotal : Integer; + sLine : string; +begin + // prevent us from stupid DIV/0 errors + nTotal := FSuccesses + FErrors.Count; + if nTotal = 0 then begin + Console.WriteLine('No results logged'); + Exit; + end; + + Console.WriteLine(''); + Console.WriteLine( StringOfChar('=',60)); + Console.WriteLine( IntToStr(nTotal)+' tests performed'); + Console.WriteLine( IntToStr(FSuccesses)+' tests succeeded ('+IntToStr(round(100*FSuccesses/nTotal))+'%)'); + Console.WriteLine( IntToStr(FErrors.Count)+' tests failed ('+IntToStr(round(100*FErrors.Count/nTotal))+'%)'); + Console.WriteLine( StringOfChar('=',60)); + if FErrors.Count > 0 then begin + Console.WriteLine('FAILED TESTS:'); + for sLine in FErrors do Console.WriteLine('- '+sLine); + Console.WriteLine( StringOfChar('=',60)); + InterlockedIncrement( ExitCode); // return <> 0 on errors + end; + Console.WriteLine(''); +end; + + + + + + +end. diff --git a/lib/delphi/test/testsuite/client/UnitTests.pas b/lib/delphi/test/testsuite/client/UnitTests.pas new file mode 100644 index 00000000000..3726c873594 --- /dev/null +++ b/lib/delphi/test/testsuite/client/UnitTests.pas @@ -0,0 +1,350 @@ +(* + * 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 UnitTests; + +{$I ../src/Thrift.Defines.inc} + +interface + +uses + Classes, Windows, SysUtils, Math, ActiveX, ComObj, + {$IFDEF SupportsAsync} System.Threading, {$ENDIF} + DateUtils, + Generics.Collections, + TestConstants, + TestLogger, + ConsoleHelper, + Thrift, + Thrift.Protocol.Compact, + Thrift.Protocol.JSON, + Thrift.Protocol, + Thrift.Transport.Pipes, + Thrift.Transport.WinHTTP, + Thrift.Transport.MsxmlHTTP, + Thrift.Transport, + Thrift.Stream, + Thrift.Test, + Thrift.WinHTTP, + Thrift.Utils, + Thrift.Configuration, + Thrift.Collections; + +type + TQuickUnitTests = class sealed + strict private + FLogger : ITestLogger; + + strict protected + // Helper + procedure StartTestGroup( const aGroup : string; const aTest : TClientTestGroup); inline; + procedure Expect( aTestResult : Boolean; const aTestInfo : string); inline; + + // Test impl + procedure JSONProtocolReadWriteTest; + procedure HashSetTest; + {$IFDEF Win64} + procedure UseInterlockedExchangeAdd64; + {$ENDIF} + + // main execution part + constructor Create( const logger : ITestLogger); reintroduce; + procedure Execute; overload; + public + destructor Destroy; override; + + class procedure Execute( const logger : ITestLogger); overload; static; + end; + + +implementation + + +constructor TQuickUnitTests.Create( const logger : ITestLogger); +begin + inherited Create; + FLogger := logger; +end; + + +destructor TQuickUnitTests.Destroy; +begin + try + FLogger := nil; //-> Release + finally + inherited Destroy; + end; +end; + + +class procedure TQuickUnitTests.Execute( const logger : ITestLogger); +var instance : TQuickUnitTests; +begin + instance := TQuickUnitTests.Create(logger); + try + instance.Execute; + finally + instance.Free; + end; +end; + + +procedure TQuickUnitTests.Execute; +begin + {$IFDEF Win64} + UseInterlockedExchangeAdd64; + {$ENDIF} + + JSONProtocolReadWriteTest; + HashSetTest; +end; + + +procedure TQuickUnitTests.StartTestGroup( const aGroup : string; const aTest : TClientTestGroup); +begin + FLogger.StartTestGroup( aGroup, aTest); +end; + + +procedure TQuickUnitTests.Expect( aTestResult : Boolean; const aTestInfo : string); +begin + FLogger.Expect( aTestResult, aTestInfo); +end; + + +{$IFDEF Win64} +procedure TQuickUnitTests.UseInterlockedExchangeAdd64; +var a,b : Int64; +begin + a := 1; + b := 2; + Thrift.Utils.InterlockedExchangeAdd64( a,b); + Expect( a = 3, 'InterlockedExchangeAdd64'); +end; +{$ENDIF} + + +procedure TQuickUnitTests.JSONProtocolReadWriteTest; +// Tests only then read/write procedures of the JSON protocol +// All tests succeed, if we can read what we wrote before +// Note that passing this test does not imply, that our JSON is really compatible to what +// other clients or servers expect as the real JSON. This is beyond the scope of this test. +var prot : IProtocol; + stm : TStringStream; + list : TThriftList; + config : IThriftConfiguration; + binary, binRead, emptyBinary : TBytes; + i,iErr : Integer; +const + TEST_SHORT = ShortInt( $FE); + TEST_SMALL = SmallInt( $FEDC); + TEST_LONG = LongInt( $FEDCBA98); + TEST_I64 = Int64( $FEDCBA9876543210); + TEST_DOUBLE = -1.234e-56; + DELTA_DOUBLE = TEST_DOUBLE * 1e-14; + TEST_STRING = 'abc-'#$00E4#$00f6#$00fc; // german umlauts (en-us: "funny chars") + // Test THRIFT-2336 and THRIFT-3404 with U+1D11E (G Clef symbol) and 'Русское Название'; + G_CLEF_AND_CYRILLIC_TEXT = #$1d11e' '#$0420#$0443#$0441#$0441#$043a#$043e#$0435' '#$041d#$0430#$0437#$0432#$0430#$043d#$0438#$0435; + G_CLEF_AND_CYRILLIC_JSON = '"\ud834\udd1e \u0420\u0443\u0441\u0441\u043a\u043e\u0435 \u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435"'; + // test both possible solidus encodings + SOLIDUS_JSON_DATA = '"one/two\/three"'; + SOLIDUS_EXCPECTED = 'one/two/three'; +begin + stm := TStringStream.Create; + try + FLogger.StartTestGroup( 'JsonProtocolTest', test_Unknown); + + config := TThriftConfigurationImpl.Create; + + // prepare binary data + binary := PrepareBinaryData( FALSE, TTestSize.Normal); + SetLength( emptyBinary, 0); // empty binary data block + + // output setup + prot := TJSONProtocolImpl.Create( + TStreamTransportImpl.Create( + nil, TThriftStreamAdapterDelphi.Create( stm, FALSE), config)); + + // write + Init( list, TType.String_, 9); + prot.WriteListBegin( list); + prot.WriteBool( TRUE); + prot.WriteBool( FALSE); + prot.WriteByte( TEST_SHORT); + prot.WriteI16( TEST_SMALL); + prot.WriteI32( TEST_LONG); + prot.WriteI64( TEST_I64); + prot.WriteDouble( TEST_DOUBLE); + prot.WriteString( TEST_STRING); + prot.WriteBinary( binary); + prot.WriteString( ''); // empty string + prot.WriteBinary( emptyBinary); // empty binary data block + prot.WriteListEnd; + + // input setup + Expect( stm.Position = stm.Size, 'Stream position/length after write'); + stm.Position := 0; + prot := TJSONProtocolImpl.Create( + TStreamTransportImpl.Create( + TThriftStreamAdapterDelphi.Create( stm, FALSE), nil, config)); + + // read and compare + list := prot.ReadListBegin; + Expect( list.ElementType = TType.String_, 'list element type'); + Expect( list.Count = 9, 'list element count'); + Expect( prot.ReadBool, 'WriteBool/ReadBool: TRUE'); + Expect( not prot.ReadBool, 'WriteBool/ReadBool: FALSE'); + Expect( prot.ReadByte = TEST_SHORT, 'WriteByte/ReadByte'); + Expect( prot.ReadI16 = TEST_SMALL, 'WriteI16/ReadI16'); + Expect( prot.ReadI32 = TEST_LONG, 'WriteI32/ReadI32'); + Expect( prot.ReadI64 = TEST_I64, 'WriteI64/ReadI64'); + Expect( abs(prot.ReadDouble-TEST_DOUBLE) < abs(DELTA_DOUBLE), 'WriteDouble/ReadDouble'); + Expect( prot.ReadString = TEST_STRING, 'WriteString/ReadString'); + binRead := prot.ReadBinary; + Expect( Length(prot.ReadString) = 0, 'WriteString/ReadString (empty string)'); + Expect( Length(prot.ReadBinary) = 0, 'empty WriteBinary/ReadBinary (empty data block)'); + prot.ReadListEnd; + + // test binary data + Expect( Length(binary) = Length(binRead), 'Binary data length check'); + iErr := -1; + for i := Low(binary) to High(binary) do begin + if binary[i] <> binRead[i] then begin + iErr := i; + Break; + end; + end; + if iErr < 0 + then Expect( TRUE, 'Binary data check ('+IntToStr(Length(binary))+' Bytes)') + else Expect( FALSE, 'Binary data check at offset '+IntToStr(iErr)); + + Expect( stm.Position = stm.Size, 'Stream position after read'); + + + // Solidus can be encoded in two ways. Make sure we can read both + stm.Position := 0; + stm.Size := 0; + stm.WriteString(SOLIDUS_JSON_DATA); + stm.Position := 0; + prot := TJSONProtocolImpl.Create( + TStreamTransportImpl.Create( + TThriftStreamAdapterDelphi.Create( stm, FALSE), nil, config)); + Expect( prot.ReadString = SOLIDUS_EXCPECTED, 'Solidus encoding'); + + + // Widechars should work too. Do they? + // After writing, we ensure that we are able to read it back + // We can't assume hex-encoding, since (nearly) any Unicode char is valid JSON + stm.Position := 0; + stm.Size := 0; + prot := TJSONProtocolImpl.Create( + TStreamTransportImpl.Create( + nil, TThriftStreamAdapterDelphi.Create( stm, FALSE), config)); + prot.WriteString( G_CLEF_AND_CYRILLIC_TEXT); + stm.Position := 0; + prot := TJSONProtocolImpl.Create( + TStreamTransportImpl.Create( + TThriftStreamAdapterDelphi.Create( stm, FALSE), nil, config)); + FLogger.Expect( prot.ReadString = G_CLEF_AND_CYRILLIC_TEXT, 'Writing JSON with chars > 8 bit'); + + // Widechars should work with hex-encoding too. Do they? + stm.Position := 0; + stm.Size := 0; + stm.WriteString( G_CLEF_AND_CYRILLIC_JSON); + stm.Position := 0; + prot := TJSONProtocolImpl.Create( + TStreamTransportImpl.Create( + TThriftStreamAdapterDelphi.Create( stm, FALSE), nil, config)); + FLogger.Expect( prot.ReadString = G_CLEF_AND_CYRILLIC_TEXT, 'Reading JSON with chars > 8 bit'); + + + finally + stm.Free; + prot := nil; //-> Release + FLogger.StartTestGroup( '', test_Unknown); // no more tests here + end; +end; + + +procedure TQuickUnitTests.HashSetTest; +var container : IThriftHashSet; + testdata : array of Integer; + i : Integer; +const + TEST_COUNT = 4096; +begin + StartTestGroup( 'IThriftHashSet implementation', test_Containers); + + // prepare test data + SetLength( testdata, 5); + testdata[0] := -2; + testdata[1] := 0; + testdata[2] := 42; + testdata[3] := MaxInt; + testdata[4] := Low(Integer); + + // first insert + container := TThriftHashSetImpl.Create; + for i in testdata do begin + Expect( container.Add( i), 'add first '+IntToStr(i)); + Expect( container.Contains( i), 'contains '+IntToStr(i)); + end; + Expect( container.Count = Length(testdata), 'container size'); + + // insert again + for i in testdata do begin + Expect( not container.Add( i), 'add second '+IntToStr(i)); + Expect( container.Contains( i), 'contains '+IntToStr(i)); + end; + Expect( container.Count = Length(testdata), 'container size'); + + // remove + for i in testdata do begin + Expect( container.Remove( i), 'first remove '+IntToStr(i)); + Expect( not container.Contains( i), 'not contains '+IntToStr(i)); + end; + Expect( container.Count = 0, 'container size'); + + // remove again + for i in testdata do begin + Expect( not container.Remove( i), 'second remove '+IntToStr(i)); + Expect( not container.Contains( i), 'not contains '+IntToStr(i)); + end; + Expect( container.Count = 0, 'container size'); + + // append and clear + for i := 0 to TEST_COUNT-1 do begin + container.Add(-i); + container.Add(+i); + end; + Expect( container.Count = 2*TEST_COUNT-1, 'container size check'); + Expect( not container.Contains( -TEST_COUNT), 'element not contained'); + Expect( not container.Contains( TEST_COUNT), 'element not contained'); + container.Clear; + Expect( container.Count = 0, 'count=0 after clear'); +end; + + + + + + + + +end. diff --git a/lib/delphi/test/TestServer.pas b/lib/delphi/test/testsuite/server/TestServer.pas similarity index 100% rename from lib/delphi/test/TestServer.pas rename to lib/delphi/test/testsuite/server/TestServer.pas diff --git a/lib/delphi/test/TestServerEvents.pas b/lib/delphi/test/testsuite/server/TestServerEvents.pas similarity index 100% rename from lib/delphi/test/TestServerEvents.pas rename to lib/delphi/test/testsuite/server/TestServerEvents.pas diff --git a/lib/erl/Makefile.am b/lib/erl/Makefile.am index 23ebb778908..4259a1f5a14 100644 --- a/lib/erl/Makefile.am +++ b/lib/erl/Makefile.am @@ -78,6 +78,9 @@ dist-hook: $(RM) -r $(distdir)/test/gen-erl/ $(RM) $(distdir)/$(THRIFT_OMIT_FILE) +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ include \ src \ diff --git a/lib/erl/rebar.config b/lib/erl/rebar.config index c3149b4c088..7f80cfdabad 100644 --- a/lib/erl/rebar.config +++ b/lib/erl/rebar.config @@ -39,7 +39,7 @@ ]}. {plugins, [ - {erlfmt, "1.1.0"} + {erlfmt, "1.5.0"} ]}. {erlfmt, [ diff --git a/lib/erl/src/thrift.app.src b/lib/erl/src/thrift.app.src index 0e25b675592..c0d4bab9b60 100644 --- a/lib/erl/src/thrift.app.src +++ b/lib/erl/src/thrift.app.src @@ -21,8 +21,8 @@ % A quick description of the application. {description, "Thrift bindings"}, - % The version of the applicaton - {vsn, "0.20.0"}, + % The version of the applicaton + {vsn, "0.22.0"}, % All modules used by the application. {modules, []}, diff --git a/lib/go/Makefile.am b/lib/go/Makefile.am index 18b6b75f46e..3bfefbc2209 100644 --- a/lib/go/Makefile.am +++ b/lib/go/Makefile.am @@ -48,6 +48,9 @@ clean-local: all-local: $(GO) build $(GOBUILDEXTRA) ./thrift +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ thrift \ coding_standards.md \ diff --git a/lib/go/test/ClientMiddlewareExceptionTest.thrift b/lib/go/test/ClientMiddlewareExceptionTest.thrift index 647c4335939..b48a611fc0a 100644 --- a/lib/go/test/ClientMiddlewareExceptionTest.thrift +++ b/lib/go/test/ClientMiddlewareExceptionTest.thrift @@ -25,11 +25,11 @@ exception Exception2 { // This is a special case, we want to make sure that the middleware don't // accidentally pull result as error. -exception FooResponse { +struct/*exception*/ FooResponse { // returning an exception by any means other than "throws" is illegal } service ClientMiddlewareExceptionTest { - FooResponse foo() throws( + FooResponse foo() throws( // returning an exception by any means other than "throws" is illegal 1: Exception1 error1, 2: Exception2 error2, ) diff --git a/lib/go/test/ForwardType.thrift b/lib/go/test/ForwardType.thrift index 0433c97cfdc..9e3670ef610 100644 --- a/lib/go/test/ForwardType.thrift +++ b/lib/go/test/ForwardType.thrift @@ -25,6 +25,7 @@ struct Struct { 1: optional Exc foo } -exception Exc { +// FIX: Use of "exception" is illegal. An exception is not a normal struct type and cannot be used as such. +struct Exc { 1: optional i32 code } diff --git a/lib/go/test/Makefile.am b/lib/go/test/Makefile.am index 22fad9e42d9..d76f24815dd 100644 --- a/lib/go/test/Makefile.am +++ b/lib/go/test/Makefile.am @@ -62,7 +62,8 @@ gopath: $(THRIFT) $(THRIFTTEST) \ ProcessorMiddlewareTest.thrift \ ClientMiddlewareExceptionTest.thrift \ ValidateTest.thrift \ - ForwardType.thrift + ForwardType.thrift \ + StringParseAllocationTest.thrift mkdir -p gopath/src grep -v list.*map.*list.*map $(THRIFTTEST) | grep -v 'set' > ThriftTest.thrift $(THRIFT) $(THRIFTARGS) -r IncludesTest.thrift @@ -98,6 +99,7 @@ gopath: $(THRIFT) $(THRIFTTEST) \ $(THRIFT) $(THRIFTARGS) ClientMiddlewareExceptionTest.thrift $(THRIFT) $(THRIFTARGS) ValidateTest.thrift $(THRIFT) $(THRIFTARGS) ForwardType.thrift + $(THRIFT) $(THRIFTARGS) StringParseAllocationTest.thrift ln -nfs ../../tests gopath/src/tests cp -r ./dontexportrwtest gopath/src touch gopath @@ -134,6 +136,9 @@ clean-local: client: stubs $(GO) run TestClient.go +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ dontexportrwtest \ tests \ @@ -171,6 +176,7 @@ EXTRA_DIST = \ RefAnnotationFieldsTest.thrift \ RequiredFieldTest.thrift \ ServicesTest.thrift \ + StringParseAllocationTest.thrift \ TypedefFieldTest.thrift \ UnionBinaryTest.thrift \ UnionDefaultValueTest.thrift \ diff --git a/lib/go/test/StringParseAllocationTest.thrift b/lib/go/test/StringParseAllocationTest.thrift new file mode 100644 index 00000000000..0ede9a52be1 --- /dev/null +++ b/lib/go/test/StringParseAllocationTest.thrift @@ -0,0 +1,22 @@ +/* + * 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. + */ + +struct StringStruct { + 1: required string example +} diff --git a/lib/go/test/UnionBinaryTest.thrift b/lib/go/test/UnionBinaryTest.thrift index f77112bdac6..8bce38d00b3 100644 --- a/lib/go/test/UnionBinaryTest.thrift +++ b/lib/go/test/UnionBinaryTest.thrift @@ -21,5 +21,6 @@ union Sample { 1: map u1, 2: binary u2, - 3: list u3 + 3: list u3, + 4: set u4, } diff --git a/lib/go/test/fuzz/Makefile.am b/lib/go/test/fuzz/Makefile.am index 9677f4f0016..a481e9583d9 100644 --- a/lib/go/test/fuzz/Makefile.am +++ b/lib/go/test/fuzz/Makefile.am @@ -27,6 +27,9 @@ check: gopathfuzz clean-local: $(RM) -rf gopathfuzz gen-go +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ fuzz.go \ fuzz_test.go \ diff --git a/lib/go/test/fuzz/go.mod b/lib/go/test/fuzz/go.mod index b7ddd5fcc60..11116191a64 100644 --- a/lib/go/test/fuzz/go.mod +++ b/lib/go/test/fuzz/go.mod @@ -1,6 +1,6 @@ module github.com/apache/thrift/lib/go/test/fuzz -go 1.21 +go 1.23 require github.com/apache/thrift v0.0.0-00010101000000-000000000000 diff --git a/lib/go/test/go.mod b/lib/go/test/go.mod index 0c032b70fe0..15329601594 100644 --- a/lib/go/test/go.mod +++ b/lib/go/test/go.mod @@ -1,6 +1,6 @@ module github.com/apache/thrift/lib/go/test -go 1.21 +go 1.23 require ( github.com/apache/thrift v0.0.0-00010101000000-000000000000 diff --git a/lib/go/test/tests/enum_values_test.go b/lib/go/test/tests/enum_values_test.go new file mode 100644 index 00000000000..84bd2657663 --- /dev/null +++ b/lib/go/test/tests/enum_values_test.go @@ -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. + */ + +package tests + +import ( + "slices" + "testing" + + "github.com/apache/thrift/lib/go/test/gopath/src/constoptionalfielda" +) + +func TestEnumValues(t *testing.T) { + want := []constoptionalfielda.Foo{ + constoptionalfielda.Foo_One, + constoptionalfielda.Foo_Two, + } + got := slices.Collect(constoptionalfielda.FooValues()) + t.Logf("FooValues = %#v", got) + if len(got) != len(want) { + t.Fatalf("Want %d values in FooValues(), got %+v", len(want), got) + } + for i, v := range want { + if got[i] != v { + t.Errorf("FooValues()[%d] got %v(%d) want %v(%d)", i, got[i], got[i], v, v) + } + } +} diff --git a/lib/go/test/tests/equals_test.go b/lib/go/test/tests/equals_test.go index b8adc770802..f56d0cb56ec 100644 --- a/lib/go/test/tests/equals_test.go +++ b/lib/go/test/tests/equals_test.go @@ -255,7 +255,7 @@ func genMapFoo() *equalstest.MapEqualsFoo { func genInt64Slice(length int) []int64 { ret := make([]int64, length) - for i := 0; i < length; i++ { + for i := range ret { ret[i] = int64(length - i) } return ret @@ -263,7 +263,7 @@ func genInt64Slice(length int) []int64 { func genStringSlice(length int) []string { ret := make([]string, length) - for i := 0; i < length; i++ { + for i := range ret { ret[i] = strconv.Itoa(length - i) } return ret @@ -271,7 +271,7 @@ func genStringSlice(length int) []string { func genBytesSlice(length int) [][]byte { ret := make([][]byte, length) - for i := 0; i < length; i++ { + for i := range ret { ret[i] = []byte(strconv.Itoa(length - i)) } return ret @@ -279,7 +279,7 @@ func genBytesSlice(length int) [][]byte { func genInt64StringMap(length int) map[int64]string { ret := make(map[int64]string, length) - for i := 0; i < length; i++ { + for i := range length { ret[int64(i)] = strconv.Itoa(i) } return ret diff --git a/lib/go/test/tests/header_zlib_test.go b/lib/go/test/tests/header_zlib_test.go new file mode 100644 index 00000000000..cf2f849358a --- /dev/null +++ b/lib/go/test/tests/header_zlib_test.go @@ -0,0 +1,206 @@ +/* + * 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 tests + +import ( + "context" + "errors" + "io" + "net" + "sync/atomic" + "testing" + "time" + + "github.com/apache/thrift/lib/go/test/gopath/src/servicestest" + "github.com/apache/thrift/lib/go/thrift" +) + +type zlibTestHandler struct { + servicestest.AServ + + tb testing.TB + text string +} + +func (z zlibTestHandler) Stringfunc_1int_1s(ctx context.Context, i int64, s string) (string, error) { + if s != z.text { + z.tb.Errorf("string arg got %q want %q", s, z.text) + } + return z.text, nil +} + +type countingProxy struct { + // Need to fill when constructing + tb testing.TB + remoteAddr net.Addr + + // internal states + listener net.Listener + clientWritten atomic.Int64 + serverWritten atomic.Int64 +} + +func (cp *countingProxy) getAndResetCounters() (req, resp int64) { + req = cp.clientWritten.Swap(0) + resp = cp.serverWritten.Swap(0) + return req, resp +} + +func (cp *countingProxy) serve() { + cp.tb.Helper() + + listener, err := net.Listen("tcp", ":0") + if err != nil { + cp.tb.Fatalf("Failed to listen proxy: %v", err) + } + go func() { + for { + client, err := listener.Accept() + if err != nil { + if !errors.Is(err, io.EOF) && !errors.Is(err, net.ErrClosed) { + cp.tb.Errorf("proxy accept error: %v", err) + } + return + } + server, err := net.Dial(cp.remoteAddr.Network(), cp.remoteAddr.String()) + if err != nil { + cp.tb.Logf("proxy failed to dial server %v: %v", cp.remoteAddr, err) + } + proxy := func(read, write net.Conn, count *atomic.Int64) { + var buf [1024]byte + for { + n, err := read.Read(buf[:]) + if n > 0 { + count.Add(int64(n)) + if _, err := write.Write(buf[:n]); err != nil { + cp.tb.Errorf("proxy write error: %v", err) + } + } + if err != nil { + if !errors.Is(err, io.EOF) && !errors.Is(err, net.ErrClosed) { + cp.tb.Errorf("proxy read error: %v", err) + } + read.Close() + write.Close() + return + } + } + } + // Read from client + go proxy(client, server, &cp.clientWritten) + // Read from server + go proxy(server, client, &cp.serverWritten) + } + }() + cp.listener = listener +} + +func TestTHeaderZlibClient(t *testing.T) { + // Some text that zlib should be able to compress + const text = `Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.` + + socket, err := thrift.NewTServerSocket(":0") + if err != nil { + t.Fatalf("Failed to create server socket: %v", err) + } + // Call listen to reserve a port and check for any issues early + if err := socket.Listen(); err != nil { + t.Fatalf("Failed to listen server socket: %v", err) + } + server := thrift.NewTSimpleServer4( + servicestest.NewAServProcessor(zlibTestHandler{ + tb: t, + text: text, + }), + socket, + thrift.NewTHeaderTransportFactoryConf(nil, nil), + thrift.NewTHeaderProtocolFactoryConf(nil), + ) + go server.Serve() + // give the server a little time to start serving + time.Sleep(10 * time.Millisecond) + t.Cleanup(func() { + server.Stop() + }) + t.Logf("server running on %v", socket.Addr()) + + proxy := countingProxy{ + tb: t, + remoteAddr: socket.Addr(), + } + proxy.serve() + t.Cleanup(func() { + proxy.listener.Close() + }) + t.Logf("proxy running on %v", proxy.listener.Addr()) + + clientRoundtrip := func(cfg *thrift.TConfiguration) { + t.Helper() + + socket := thrift.NewTSocketConf(proxy.listener.Addr().String(), cfg) + if err := socket.Open(); err != nil { + t.Errorf("failed to open socket: %v", err) + return + } + defer socket.Close() + protoFactory := thrift.NewTHeaderProtocolFactoryConf(cfg) + client := thrift.NewTStandardClient( + protoFactory.GetProtocol(socket), + protoFactory.GetProtocol(socket), + ) + c := servicestest.NewAServClient(client) + got, err := c.Stringfunc_1int_1s(context.Background(), 0, text) + if err != nil { + t.Errorf("Stringfunc_1int_1s call failed: %v", err) + return + } + if got != text { + t.Errorf("Stringfunc_1int_1s got %q want %q", got, text) + } + } + + clientRoundtrip(nil) + nozlibReq, nozlibResp := proxy.getAndResetCounters() + t.Logf("nozlib request size: %d, response size: %d", nozlibReq, nozlibResp) + + clientRoundtrip(&thrift.TConfiguration{ + THeaderTransforms: []thrift.THeaderTransformID{thrift.TransformZlib}, + }) + zlibReq, zlibResp := proxy.getAndResetCounters() + t.Logf("zlib request size: %d, response size: %d", zlibReq, zlibResp) + + if zlibReq >= nozlibReq { + t.Errorf("zlib request size %d >= nozlib request size %d", zlibReq, nozlibReq) + } + if zlibResp >= nozlibResp { + t.Errorf("zlib response size %d >= nozlib response size %d", zlibResp, nozlibResp) + } + + clientRoundtrip(nil) + nozlibReq2, nozlibResp2 := proxy.getAndResetCounters() + t.Logf("nozlib2 request size: %d, response size: %d", nozlibReq, nozlibResp) + + if nozlibReq2 != nozlibReq { + t.Errorf("nozlib request 2 size %d != nozlib request size %d", nozlibReq2, nozlibReq) + } + if nozlibResp2 != nozlibResp { + t.Errorf("nozlib response 2 size %d != nozlib response size %d", nozlibResp2, nozlibResp) + } +} diff --git a/lib/go/test/tests/processor_middleware_test.go b/lib/go/test/tests/processor_middleware_test.go index 1bd911cfe60..aedd93f2279 100644 --- a/lib/go/test/tests/processor_middleware_test.go +++ b/lib/go/test/tests/processor_middleware_test.go @@ -32,9 +32,12 @@ import ( const errorMessage = "foo error" -type serviceImpl struct{} +type serviceImpl struct { + sleepTime time.Duration +} -func (serviceImpl) Ping(_ context.Context) (err error) { +func (s serviceImpl) Ping(_ context.Context) (err error) { + time.Sleep(s.sleepTime) return &processormiddlewaretest.Error{ Foo: thrift.StringPtr(errorMessage), } @@ -67,9 +70,14 @@ func checkError(tb testing.TB, err error) { } func TestProcessorMiddleware(t *testing.T) { - const timeout = time.Second + const ( + sleepTime = 10 * time.Millisecond + timeout = sleepTime / 5 + ) - processor := processormiddlewaretest.NewServiceProcessor(&serviceImpl{}) + processor := processormiddlewaretest.NewServiceProcessor(&serviceImpl{ + sleepTime: sleepTime, + }) serverTransport, err := thrift.NewTServerSocket("127.0.0.1:0") if err != nil { t.Fatalf("Could not find available server port: %v", err) @@ -80,7 +88,9 @@ func TestProcessorMiddleware(t *testing.T) { thrift.NewTHeaderTransportFactoryConf(nil, nil), thrift.NewTHeaderProtocolFactoryConf(nil), ) - defer server.Stop() + t.Cleanup(func() { + server.Stop() + }) var wg sync.WaitGroup wg.Add(1) go func() { @@ -103,6 +113,14 @@ func TestProcessorMiddleware(t *testing.T) { client := processormiddlewaretest.NewServiceClient(thrift.NewTStandardClient(protocol, protocol)) - err = client.Ping(context.Background()) - checkError(t, err) + for label, timeout := range map[string]time.Duration{ + "enough-time": sleepTime * 10, + "not-enough-time": sleepTime / 2, + } { + t.Run(label, func(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), timeout) + t.Cleanup(cancel) + client.Ping(ctx) + }) + } } diff --git a/lib/go/test/tests/string_parse_allocation_test.go b/lib/go/test/tests/string_parse_allocation_test.go new file mode 100644 index 00000000000..56163b7d070 --- /dev/null +++ b/lib/go/test/tests/string_parse_allocation_test.go @@ -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. + */ + +package tests + +import ( + "context" + "fmt" + "strings" + "testing" + + "github.com/apache/thrift/lib/go/test/gopath/src/stringparseallocationtest" + "github.com/apache/thrift/lib/go/thrift" +) + +func TestSimpleJsonStringParse_Allocations(t *testing.T) { + byteAllocationLimit := 100 * 1024 // 100 KB + res := testing.Benchmark(BenchmarkSimpleJsonStringParse_Allocations) + if res.AllocedBytesPerOp() > int64(byteAllocationLimit) { + t.Errorf("Total memory allocation size too high: %d (> %d)", res.AllocedBytesPerOp(), byteAllocationLimit) + } +} + +func BenchmarkSimpleJsonStringParse_Allocations(b *testing.B) { + b.ReportAllocs() + b.StopTimer() + numEscapedQuotes := 1000 + var sb strings.Builder + for range numEscapedQuotes { + sb.WriteString(`\"`) + } + + testString := fmt.Sprintf(`{"1": {"str": "this is a test with %d of escaped quotes %s"}}`, numEscapedQuotes, sb.String()) + stringStruct := stringparseallocationtest.NewStringStruct() + transport := thrift.NewTMemoryBuffer() + p := thrift.NewTJSONProtocol(transport) + + for range b.N { + transport.Reset() + transport.WriteString(testString) + transport.Flush(context.Background()) + b.StartTimer() + _ = stringStruct.Read(context.Background(), p) + b.StopTimer() + } +} diff --git a/lib/go/test/tests/validate_test.go b/lib/go/test/tests/validate_test.go index 957a8df03c7..52e059ab9d5 100644 --- a/lib/go/test/tests/validate_test.go +++ b/lib/go/test/tests/validate_test.go @@ -107,7 +107,7 @@ func TestBasicValidator(t *testing.T) { } bt = validatetest.NewBasicTest() bt.Map1 = make(map[string]string) - for i := 0; i < 11; i++ { + for i := range 11 { bt.Map1[strconv.Itoa(i)] = strconv.Itoa(i) } if err := bt.Validate(); err == nil { @@ -149,7 +149,7 @@ func TestBasicValidator(t *testing.T) { t.Errorf("Error cannot be unwrapped into *ValidationError: %v", err) } bt = validatetest.NewBasicTest() - for i := 0; i < 11; i++ { + for range 11 { bt.Set1 = append(bt.Set1, "0") } if err := bt.Validate(); err == nil { @@ -272,7 +272,7 @@ func TestFieldReference(t *testing.T) { frt = validatetest.NewFieldReferenceTest() frt.MaxSize = 8 frt.Map0 = make(map[string]string) - for i := 0; i < 9; i++ { + for i := range 9 { frt.Map0[strconv.Itoa(i)] = strconv.Itoa(i) } if err := frt.Validate(); err == nil { @@ -289,7 +289,7 @@ func TestFieldReference(t *testing.T) { } frt = validatetest.NewFieldReferenceTest() frt.MaxSize = 8 - for i := 0; i < 9; i++ { + for range 9 { frt.List0 = append(frt.List0, "0") } if err := frt.Validate(); err == nil { @@ -306,7 +306,7 @@ func TestFieldReference(t *testing.T) { } frt = validatetest.NewFieldReferenceTest() frt.MaxSize = 8 - for i := 0; i < 9; i++ { + for range 9 { frt.Set0 = append(frt.Set0, "0") } if err := frt.Validate(); err == nil { diff --git a/lib/go/test/tests/write_texception_test.go b/lib/go/test/tests/write_texception_test.go new file mode 100644 index 00000000000..3241364f88e --- /dev/null +++ b/lib/go/test/tests/write_texception_test.go @@ -0,0 +1,69 @@ +/* + * 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 tests + +import ( + "context" + "errors" + "testing" + + "github.com/apache/thrift/lib/go/test/gopath/src/unionbinarytest" + "github.com/apache/thrift/lib/go/thrift" +) + +func TestWriteUnionTException(t *testing.T) { + // See https://issues.apache.org/jira/browse/THRIFT-5845 + s := unionbinarytest.NewSample() + proto := thrift.NewTBinaryProtocolConf(thrift.NewTMemoryBuffer(), nil) + err := s.Write(context.Background(), proto) + t.Log(err) + if err == nil { + t.Fatal("Writing empty union did not produce error") + } + var te thrift.TException + if !errors.As(err, &te) { + t.Fatalf("Error from writing empty union is not TException: (%T) %v", err, err) + } + if typ := te.TExceptionType(); typ != thrift.TExceptionTypeProtocol && typ != thrift.TExceptionTypeTransport { + t.Errorf("Got TExceptionType %v, want one of TProtocolException or TTransportException", typ) + } +} + +func TestWriteSetTException(t *testing.T) { + // See https://issues.apache.org/jira/browse/THRIFT-5845 + s := unionbinarytest.NewSample() + s.U4 = []string{ + "foo", + "foo", // duplicate + } + proto := thrift.NewTBinaryProtocolConf(thrift.NewTMemoryBuffer(), nil) + err := s.Write(context.Background(), proto) + t.Log(err) + if err == nil { + t.Fatal("Writing duplicate set did not produce error") + } + var te thrift.TException + if !errors.As(err, &te) { + t.Fatalf("Error from writing duplicate set is not TException: (%T) %v", err, err) + } + if typ := te.TExceptionType(); typ != thrift.TExceptionTypeProtocol && typ != thrift.TExceptionTypeTransport { + t.Errorf("Got TExceptionType %v, want one of TProtocolException or TTransportException", typ) + } +} diff --git a/lib/go/thrift/binary_protocol_test.go b/lib/go/thrift/binary_protocol_test.go index 88bfd26b7ea..67f99238d83 100644 --- a/lib/go/thrift/binary_protocol_test.go +++ b/lib/go/thrift/binary_protocol_test.go @@ -112,7 +112,7 @@ func generateSafeReadBytesBenchmark(askedSize int32, dataSize int) func(b *testi return func(b *testing.B) { data := make([]byte, dataSize) b.ResetTimer() - for i := 0; i < b.N; i++ { + for range b.N { safeReadBytes(askedSize, bytes.NewReader(data)) } } diff --git a/lib/go/thrift/configuration.go b/lib/go/thrift/configuration.go index de27edd674c..a9565d399df 100644 --- a/lib/go/thrift/configuration.go +++ b/lib/go/thrift/configuration.go @@ -56,47 +56,47 @@ const ( // // For example, say you want to migrate this old code into using TConfiguration: // -// sccket, err := thrift.NewTSocketTimeout("host:port", time.Second, time.Second) -// transFactory := thrift.NewTFramedTransportFactoryMaxLength( -// thrift.NewTTransportFactory(), -// 1024 * 1024 * 256, -// ) -// protoFactory := thrift.NewTBinaryProtocolFactory(true, true) +// socket, err := thrift.NewTSocketTimeout("host:port", time.Second, time.Second) +// transFactory := thrift.NewTFramedTransportFactoryMaxLength( +// thrift.NewTTransportFactory(), +// 1024 * 1024 * 256, +// ) +// protoFactory := thrift.NewTBinaryProtocolFactory(true, true) // // This is the wrong way to do it because in the end the TConfiguration used by // socket and transFactory will be overwritten by the one used by protoFactory // because of TConfiguration propagation: // -// // bad example, DO NOT USE -// sccket := thrift.NewTSocketConf("host:port", &thrift.TConfiguration{ -// ConnectTimeout: time.Second, -// SocketTimeout: time.Second, -// }) -// transFactory := thrift.NewTFramedTransportFactoryConf( -// thrift.NewTTransportFactory(), -// &thrift.TConfiguration{ -// MaxFrameSize: 1024 * 1024 * 256, -// }, -// ) -// protoFactory := thrift.NewTBinaryProtocolFactoryConf(&thrift.TConfiguration{ -// TBinaryStrictRead: thrift.BoolPtr(true), -// TBinaryStrictWrite: thrift.BoolPtr(true), -// }) +// // bad example, DO NOT USE +// socket := thrift.NewTSocketConf("host:port", &thrift.TConfiguration{ +// ConnectTimeout: time.Second, +// SocketTimeout: time.Second, +// }) +// transFactory := thrift.NewTFramedTransportFactoryConf( +// thrift.NewTTransportFactory(), +// &thrift.TConfiguration{ +// MaxFrameSize: 1024 * 1024 * 256, +// }, +// ) +// protoFactory := thrift.NewTBinaryProtocolFactoryConf(&thrift.TConfiguration{ +// TBinaryStrictRead: thrift.BoolPtr(true), +// TBinaryStrictWrite: thrift.BoolPtr(true), +// }) // // This is the correct way to do it: // -// conf := &thrift.TConfiguration{ -// ConnectTimeout: time.Second, -// SocketTimeout: time.Second, +// conf := &thrift.TConfiguration{ +// ConnectTimeout: time.Second, +// SocketTimeout: time.Second, // -// MaxFrameSize: 1024 * 1024 * 256, +// MaxFrameSize: 1024 * 1024 * 256, // -// TBinaryStrictRead: thrift.BoolPtr(true), -// TBinaryStrictWrite: thrift.BoolPtr(true), -// } -// sccket := thrift.NewTSocketConf("host:port", conf) -// transFactory := thrift.NewTFramedTransportFactoryConf(thrift.NewTTransportFactory(), conf) -// protoFactory := thrift.NewTBinaryProtocolFactoryConf(conf) +// TBinaryStrictRead: thrift.BoolPtr(true), +// TBinaryStrictWrite: thrift.BoolPtr(true), +// } +// socket := thrift.NewTSocketConf("host:port", conf) +// transFactory := thrift.NewTFramedTransportFactoryConf(thrift.NewTTransportFactory(), conf) +// protoFactory := thrift.NewTBinaryProtocolFactoryConf(conf) // // [1]: https://github.com/apache/thrift/blob/master/doc/specs/thrift-tconfiguration.md type TConfiguration struct { @@ -132,6 +132,8 @@ type TConfiguration struct { // THeaderProtocolIDPtr and THeaderProtocolIDPtrMust helper functions // are provided to help filling this value. THeaderProtocolID *THeaderProtocolID + // The write transforms to be applied to THeaderTransport. + THeaderTransforms []THeaderTransformID // Used internally by deprecated constructors, to avoid overriding // underlying TTransport/TProtocol's cfg by accidental propagations. @@ -245,6 +247,18 @@ func (tc *TConfiguration) GetTHeaderProtocolID() THeaderProtocolID { return protoID } +// GetTHeaderTransforms returns the THeaderTransformIDs to be applied on +// THeaderTransport writing. +// +// It's nil-safe. If tc is nil, empty slice will be returned (meaning no +// transforms to be applied). +func (tc *TConfiguration) GetTHeaderTransforms() []THeaderTransformID { + if tc == nil { + return nil + } + return tc.THeaderTransforms +} + // THeaderProtocolIDPtr validates and returns the pointer to id. // // If id is not a valid THeaderProtocolID, a pointer to THeaderProtocolDefault diff --git a/lib/go/thrift/duplicate_protocol.go b/lib/go/thrift/duplicate_protocol.go index 6413909d482..a9eb7eb24e1 100644 --- a/lib/go/thrift/duplicate_protocol.go +++ b/lib/go/thrift/duplicate_protocol.go @@ -198,6 +198,10 @@ func (tdtp *TDuplicateToProtocol) ReadStructEnd(ctx context.Context) (err error) func (tdtp *TDuplicateToProtocol) ReadFieldBegin(ctx context.Context) (name string, typeId TType, id int16, err error) { name, typeId, id, err = tdtp.Delegate.ReadFieldBegin(ctx) + if typeId == STOP { + tdtp.DuplicateTo.WriteFieldStop(ctx) + return + } tdtp.DuplicateTo.WriteFieldBegin(ctx, name, typeId, id) return } diff --git a/lib/go/thrift/duplicate_protocol_test.go b/lib/go/thrift/duplicate_protocol_test.go new file mode 100644 index 00000000000..6674f0442c5 --- /dev/null +++ b/lib/go/thrift/duplicate_protocol_test.go @@ -0,0 +1,52 @@ +package thrift + +import ( + "bytes" + "context" + "encoding/json" + "testing" +) + +func TestDuplicateToJSONReadMakesEqualJSON(t *testing.T) { + delegateBuf := NewTMemoryBuffer() + iprot := NewTJSONProtocolFactory().GetProtocol(delegateBuf) + + s := NewMyTestStruct() + ctx := context.Background() + s.Write(ctx, iprot) + + iprot.Flush(ctx) + jsonBytesWritten := delegateBuf.Bytes() + + if err := json.Unmarshal(jsonBytesWritten, NewMyTestStruct()); err != nil { + t.Errorf("error unmarshaling written bytes: %s", err) + } + + duplicateBuf := NewTMemoryBuffer() + dupProto := NewTJSONProtocolFactory().GetProtocol(duplicateBuf) + proto := &TDuplicateToProtocol{ + Delegate: NewTJSONProtocolFactory().GetProtocol(delegateBuf), + DuplicateTo: dupProto, + } + + if err := s.Read(ctx, proto); err != nil { + t.Errorf("error reading struct from DuplicateTo: %s", err) + } + dupProto.Flush(ctx) + + jsonBytesRead := duplicateBuf.Bytes() + + if !bytes.Equal(jsonBytesWritten, jsonBytesRead) { + t.Errorf(`bytes read into duplicate do not equal bytes written + read: + %s + written: + %s + `, jsonBytesRead, jsonBytesWritten) + } + + dup := NewMyTestStruct() + if err := dup.Read(ctx, dupProto); err != nil { + t.Errorf("error reading struct from duplicated protocol: %s", err) + } +} diff --git a/lib/go/thrift/exception.go b/lib/go/thrift/exception.go index e2f1728eac5..5b4cad96faa 100644 --- a/lib/go/thrift/exception.go +++ b/lib/go/thrift/exception.go @@ -121,20 +121,20 @@ var _ TException = wrappedTException{} // // For a endpoint defined in thrift IDL like this: // -// service MyService { -// FooResponse foo(1: FooRequest request) throws ( -// 1: Exception1 error1, -// 2: Exception2 error2, -// ) -// } +// service MyService { +// FooResponse foo(1: FooRequest request) throws ( +// 1: Exception1 error1, +// 2: Exception2 error2, +// ) +// } // // The thrift compiler generated go code for the result TStruct would be like: // -// type MyServiceFooResult struct { -// Success *FooResponse `thrift:"success,0" db:"success" json:"success,omitempty"` -// Error1 *Exception1 `thrift:"error1,1" db:"error1" json:"error1,omitempty"` -// Error2 *Exception2 `thrift:"error2,2" db:"error2" json:"error2,omitempty"` -// } +// type MyServiceFooResult struct { +// Success *FooResponse `thrift:"success,0" db:"success" json:"success,omitempty"` +// Error1 *Exception1 `thrift:"error1,1" db:"error1" json:"error1,omitempty"` +// Error2 *Exception2 `thrift:"error2,2" db:"error2" json:"error2,omitempty"` +// } // // And this function extracts the first non-nil exception out of // *MyServiceFooResult. @@ -144,7 +144,7 @@ func ExtractExceptionFromResult(result TStruct) error { return nil } typ := v.Type() - for i := 0; i < v.NumField(); i++ { + for i := range v.NumField() { if typ.Field(i).Name == "Success" { continue } diff --git a/lib/go/thrift/framed_transport_test.go b/lib/go/thrift/framed_transport_test.go index d23ec595e6f..e5aa4700cde 100644 --- a/lib/go/thrift/framed_transport_test.go +++ b/lib/go/thrift/framed_transport_test.go @@ -42,7 +42,7 @@ func TestTFramedTransportReuseTransport(t *testing.T) { writer := NewTFramedTransport(trans) t.Run("pair", func(t *testing.T) { - for i := 0; i < n; i++ { + for i := range n { // write if _, err := io.Copy(writer, strings.NewReader(content)); err != nil { t.Fatalf("Failed to write on #%d: %v", i, err) @@ -64,7 +64,7 @@ func TestTFramedTransportReuseTransport(t *testing.T) { t.Run("batched", func(t *testing.T) { // write - for i := 0; i < n; i++ { + for i := range n { if _, err := io.Copy(writer, strings.NewReader(content)); err != nil { t.Fatalf("Failed to write on #%d: %v", i, err) } @@ -74,7 +74,7 @@ func TestTFramedTransportReuseTransport(t *testing.T) { } // read - for i := 0; i < n; i++ { + for i := range n { const ( size = len(content) ) diff --git a/lib/go/thrift/header_protocol.go b/lib/go/thrift/header_protocol.go index 36777b4ca00..bec84b85c49 100644 --- a/lib/go/thrift/header_protocol.go +++ b/lib/go/thrift/header_protocol.go @@ -119,6 +119,11 @@ func (p *THeaderProtocol) ClearWriteHeaders() { } // AddTransform add a transform for writing. +// +// Deprecated: This only applies to the next message written, and the next read +// message will cause write transforms to be reset from what's configured in +// TConfiguration. For sticky transforms, use TConfiguration.THeaderTransforms +// instead. func (p *THeaderProtocol) AddTransform(transform THeaderTransformID) error { return p.transport.AddTransform(transform) } diff --git a/lib/go/thrift/header_protocol_test.go b/lib/go/thrift/header_protocol_test.go index 48a69bf23b0..dfd84f83012 100644 --- a/lib/go/thrift/header_protocol_test.go +++ b/lib/go/thrift/header_protocol_test.go @@ -39,4 +39,24 @@ func TestReadWriteHeaderProtocol(t *testing.T) { })) }, ) + + t.Run( + "binary-zlib", + func(t *testing.T) { + ReadWriteProtocolTest(t, NewTHeaderProtocolFactoryConf(&TConfiguration{ + THeaderProtocolID: THeaderProtocolIDPtrMust(THeaderProtocolBinary), + THeaderTransforms: []THeaderTransformID{TransformZlib}, + })) + }, + ) + + t.Run( + "compact-zlib", + func(t *testing.T) { + ReadWriteProtocolTest(t, NewTHeaderProtocolFactoryConf(&TConfiguration{ + THeaderProtocolID: THeaderProtocolIDPtrMust(THeaderProtocolCompact), + THeaderTransforms: []THeaderTransformID{TransformZlib}, + })) + }, + ) } diff --git a/lib/go/thrift/header_transport.go b/lib/go/thrift/header_transport.go index 3aea5a9888d..d6d64160af3 100644 --- a/lib/go/thrift/header_transport.go +++ b/lib/go/thrift/header_transport.go @@ -128,7 +128,7 @@ var _ io.ReadCloser = (*TransformReader)(nil) // // If you don't know the closers capacity beforehand, just use // -// &TransformReader{Reader: baseReader} +// &TransformReader{Reader: baseReader} // // instead would be sufficient. func NewTransformReaderWithCapacity(baseReader io.Reader, capacity int) *TransformReader { @@ -151,6 +151,11 @@ func (tr *TransformReader) Close() error { } // AddTransform adds a transform. +// +// Deprecated: This only applies to the next message written, and the next read +// message will cause write transforms to be reset from what's configured in +// TConfiguration. For sticky transforms, use TConfiguration.THeaderTransforms +// instead. func (tr *TransformReader) AddTransform(id THeaderTransformID) error { switch id { default: @@ -206,6 +211,25 @@ func (tw *TransformWriter) Close() error { return nil } +var zlibDefaultLevelWriterPool = newPool( + func() *zlib.Writer { + return zlib.NewWriter(nil) + }, + nil, +) + +type zlibPoolCloser struct { + writer *zlib.Writer +} + +func (z *zlibPoolCloser) Close() error { + defer func() { + z.writer.Reset(nil) + zlibDefaultLevelWriterPool.put(&z.writer) + }() + return z.writer.Close() +} + // AddTransform adds a transform. func (tw *TransformWriter) AddTransform(id THeaderTransformID) error { switch id { @@ -217,9 +241,12 @@ func (tw *TransformWriter) AddTransform(id THeaderTransformID) error { case TransformNone: // no-op case TransformZlib: - writeCloser := zlib.NewWriter(tw.Writer) + writeCloser := zlibDefaultLevelWriterPool.get() + writeCloser.Reset(tw.Writer) tw.Writer = writeCloser - tw.closers = append(tw.closers, writeCloser) + tw.closers = append(tw.closers, &zlibPoolCloser{ + writer: writeCloser, + }) } return nil } @@ -300,11 +327,12 @@ func NewTHeaderTransportConf(trans TTransport, conf *TConfiguration) *THeaderTra } PropagateTConfiguration(trans, conf) return &THeaderTransport{ - transport: trans, - reader: bufio.NewReader(trans), - writeHeaders: make(THeaderMap), - protocolID: conf.GetTHeaderProtocolID(), - cfg: conf, + transport: trans, + reader: bufio.NewReader(trans), + writeHeaders: make(THeaderMap), + writeTransforms: conf.GetTHeaderTransforms(), + protocolID: conf.GetTHeaderProtocolID(), + cfg: conf, } } @@ -449,6 +477,11 @@ func (t *THeaderTransport) parseHeaders(ctx context.Context, frameSize uint32) e } t.protocolID = THeaderProtocolID(protoID) + // Reset writeTransforms to the ones from cfg, as we are going to add + // compression transforms from what we read, we don't want to accumulate + // different transforms read from different requests + t.writeTransforms = t.cfg.GetTHeaderTransforms() + var transformCount int32 transformCount, err = hp.readVarint32() if err != nil { @@ -461,12 +494,21 @@ func (t *THeaderTransport) parseHeaders(ctx context.Context, frameSize uint32) e ) t.frameReader = reader transformIDs := make([]THeaderTransformID, transformCount) - for i := 0; i < int(transformCount); i++ { + for i := range int(transformCount) { id, err := hp.readVarint32() if err != nil { return err } - transformIDs[i] = THeaderTransformID(id) + tID := THeaderTransformID(id) + transformIDs[i] = tID + + // For compression transforms, we should also add them + // to writeTransforms so that the response (assuming we + // are reading a request) would do the same compression. + switch tID { + case TransformZlib: + t.addWriteTransformsDedupe(tID) + } } // The transform IDs on the wire was added based on the order of // writing, so on the reading side we need to reverse the order. @@ -494,7 +536,7 @@ func (t *THeaderTransport) parseHeaders(ctx context.Context, frameSize uint32) e if err != nil { return err } - for i := 0; i < int(count); i++ { + for range int(count) { key, err := hp.ReadString(ctx) if err != nil { return err @@ -544,7 +586,7 @@ func (t *THeaderTransport) Read(p []byte) (read int, err error) { // the last Read finished the frame, do endOfFrame // handling here. err = t.endOfFrame() - } else if err == io.EOF { + } else if errors.Is(err, io.EOF) { err = t.endOfFrame() if err != nil { return @@ -726,6 +768,9 @@ func (t *THeaderTransport) ClearWriteHeaders() { } // AddTransform add a transform for writing. +// +// NOTE: This is provided as a low-level API, but in general you should use +// TConfiguration.THeaderTransforms to set transforms for writing instead. func (t *THeaderTransport) AddTransform(transform THeaderTransformID) error { if !supportedTransformIDs[transform] { return NewTProtocolExceptionWithType( @@ -758,6 +803,17 @@ func (t *THeaderTransport) isFramed() bool { } } +// addWriteTransformsDedupe adds id to writeTransforms only if it's not already +// there. +func (t *THeaderTransport) addWriteTransformsDedupe(id THeaderTransformID) { + for _, existingID := range t.writeTransforms { + if existingID == id { + return + } + } + t.writeTransforms = append(t.writeTransforms, id) +} + // SetTConfiguration implements TConfigurationSetter. func (t *THeaderTransport) SetTConfiguration(cfg *TConfiguration) { PropagateTConfiguration(t.transport, cfg) diff --git a/lib/go/thrift/header_transport_test.go b/lib/go/thrift/header_transport_test.go index 125a5fd8c36..09a03313299 100644 --- a/lib/go/thrift/header_transport_test.go +++ b/lib/go/thrift/header_transport_test.go @@ -316,7 +316,7 @@ func TestTHeaderTransportReuseTransport(t *testing.T) { writer := NewTHeaderTransport(trans) t.Run("pair", func(t *testing.T) { - for i := 0; i < n; i++ { + for i := range n { // write if _, err := io.Copy(writer, strings.NewReader(content)); err != nil { t.Fatalf("Failed to write on #%d: %v", i, err) @@ -338,7 +338,7 @@ func TestTHeaderTransportReuseTransport(t *testing.T) { t.Run("batched", func(t *testing.T) { // write - for i := 0; i < n; i++ { + for i := range n { if _, err := io.Copy(writer, strings.NewReader(content)); err != nil { t.Fatalf("Failed to write on #%d: %v", i, err) } @@ -348,7 +348,7 @@ func TestTHeaderTransportReuseTransport(t *testing.T) { } // read - for i := 0; i < n; i++ { + for i := range n { const ( size = len(content) ) diff --git a/lib/go/thrift/json_protocol_test.go b/lib/go/thrift/json_protocol_test.go index 39e52d15069..1680532cfbd 100644 --- a/lib/go/thrift/json_protocol_test.go +++ b/lib/go/thrift/json_protocol_test.go @@ -451,7 +451,7 @@ func TestReadJSONProtocolBinary(t *testing.T) { if len(v) != len(value) { t.Fatalf("Bad value for %s value length %v, wrote: %v, received length: %v", thetype, len(value), s, len(v)) } - for i := 0; i < len(v); i++ { + for i := range v { if v[i] != value[i] { t.Fatalf("Bad value for %s at index %d value %v, wrote: %v, received: %v", thetype, i, value[i], s, v[i]) } diff --git a/lib/go/thrift/lowlevel_benchmarks_test.go b/lib/go/thrift/lowlevel_benchmarks_test.go index e1736557b14..b389388aaad 100644 --- a/lib/go/thrift/lowlevel_benchmarks_test.go +++ b/lib/go/thrift/lowlevel_benchmarks_test.go @@ -41,7 +41,7 @@ func BenchmarkBinaryBool_0(b *testing.B) { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteBool(b, p, trans) } } @@ -52,7 +52,7 @@ func BenchmarkBinaryByte_0(b *testing.B) { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteByte(b, p, trans) } } @@ -63,7 +63,7 @@ func BenchmarkBinaryI16_0(b *testing.B) { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteI16(b, p, trans) } } @@ -74,7 +74,7 @@ func BenchmarkBinaryI32_0(b *testing.B) { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteI32(b, p, trans) } } @@ -84,7 +84,7 @@ func BenchmarkBinaryI64_0(b *testing.B) { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteI64(b, p, trans) } } @@ -94,7 +94,7 @@ func BenchmarkBinaryDouble_0(b *testing.B) { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteDouble(b, p, trans) } } @@ -104,7 +104,7 @@ func BenchmarkBinaryString_0(b *testing.B) { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteString(b, p, trans) } } @@ -114,7 +114,7 @@ func BenchmarkBinaryBinary_0(b *testing.B) { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteBinary(b, p, trans) } } @@ -125,7 +125,7 @@ func BenchmarkBinaryBool_1(b *testing.B) { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteBool(b, p, trans) } } @@ -136,7 +136,7 @@ func BenchmarkBinaryByte_1(b *testing.B) { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteByte(b, p, trans) } } @@ -147,7 +147,7 @@ func BenchmarkBinaryI16_1(b *testing.B) { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteI16(b, p, trans) } } @@ -158,7 +158,7 @@ func BenchmarkBinaryI32_1(b *testing.B) { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteI32(b, p, trans) } } @@ -168,7 +168,7 @@ func BenchmarkBinaryI64_1(b *testing.B) { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteI64(b, p, trans) } } @@ -178,7 +178,7 @@ func BenchmarkBinaryDouble_1(b *testing.B) { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteDouble(b, p, trans) } } @@ -188,7 +188,7 @@ func BenchmarkBinaryString_1(b *testing.B) { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteString(b, p, trans) } } @@ -198,7 +198,7 @@ func BenchmarkBinaryBinary_1(b *testing.B) { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteBinary(b, p, trans) } } @@ -209,7 +209,7 @@ func BenchmarkBinaryBool_2(b *testing.B) { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteBool(b, p, trans) } } @@ -220,7 +220,7 @@ func BenchmarkBinaryByte_2(b *testing.B) { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteByte(b, p, trans) } } @@ -231,7 +231,7 @@ func BenchmarkBinaryI16_2(b *testing.B) { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteI16(b, p, trans) } } @@ -242,7 +242,7 @@ func BenchmarkBinaryI32_2(b *testing.B) { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteI32(b, p, trans) } } @@ -252,7 +252,7 @@ func BenchmarkBinaryI64_2(b *testing.B) { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteI64(b, p, trans) } } @@ -262,7 +262,7 @@ func BenchmarkBinaryDouble_2(b *testing.B) { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteDouble(b, p, trans) } } @@ -272,7 +272,7 @@ func BenchmarkBinaryString_2(b *testing.B) { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteString(b, p, trans) } } @@ -282,7 +282,7 @@ func BenchmarkBinaryBinary_2(b *testing.B) { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteBinary(b, p, trans) } } @@ -293,7 +293,7 @@ func BenchmarkCompactBool_0(b *testing.B) { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteBool(b, p, trans) } } @@ -304,7 +304,7 @@ func BenchmarkCompactByte_0(b *testing.B) { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteByte(b, p, trans) } } @@ -315,7 +315,7 @@ func BenchmarkCompactI16_0(b *testing.B) { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteI16(b, p, trans) } } @@ -326,7 +326,7 @@ func BenchmarkCompactI32_0(b *testing.B) { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteI32(b, p, trans) } } @@ -336,7 +336,7 @@ func BenchmarkCompactI64_0(b *testing.B) { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteI64(b, p, trans) } } @@ -346,7 +346,7 @@ func BenchmarkCompactDouble0(b *testing.B) { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteDouble(b, p, trans) } } @@ -356,7 +356,7 @@ func BenchmarkCompactString0(b *testing.B) { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteString(b, p, trans) } } @@ -366,7 +366,7 @@ func BenchmarkCompactBinary0(b *testing.B) { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteBinary(b, p, trans) } } @@ -377,7 +377,7 @@ func BenchmarkCompactBool_1(b *testing.B) { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteBool(b, p, trans) } } @@ -388,7 +388,7 @@ func BenchmarkCompactByte_1(b *testing.B) { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteByte(b, p, trans) } } @@ -399,7 +399,7 @@ func BenchmarkCompactI16_1(b *testing.B) { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteI16(b, p, trans) } } @@ -410,7 +410,7 @@ func BenchmarkCompactI32_1(b *testing.B) { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteI32(b, p, trans) } } @@ -420,7 +420,7 @@ func BenchmarkCompactI64_1(b *testing.B) { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteI64(b, p, trans) } } @@ -430,7 +430,7 @@ func BenchmarkCompactDouble1(b *testing.B) { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteDouble(b, p, trans) } } @@ -440,7 +440,7 @@ func BenchmarkCompactString1(b *testing.B) { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteString(b, p, trans) } } @@ -450,7 +450,7 @@ func BenchmarkCompactBinary1(b *testing.B) { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteBinary(b, p, trans) } } @@ -461,7 +461,7 @@ func BenchmarkCompactBool_2(b *testing.B) { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteBool(b, p, trans) } } @@ -472,7 +472,7 @@ func BenchmarkCompactByte_2(b *testing.B) { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteByte(b, p, trans) } } @@ -483,7 +483,7 @@ func BenchmarkCompactI16_2(b *testing.B) { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteI16(b, p, trans) } } @@ -494,7 +494,7 @@ func BenchmarkCompactI32_2(b *testing.B) { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteI32(b, p, trans) } } @@ -504,7 +504,7 @@ func BenchmarkCompactI64_2(b *testing.B) { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteI64(b, p, trans) } } @@ -514,7 +514,7 @@ func BenchmarkCompactDouble2(b *testing.B) { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteDouble(b, p, trans) } } @@ -524,7 +524,7 @@ func BenchmarkCompactString2(b *testing.B) { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteString(b, p, trans) } } @@ -534,7 +534,7 @@ func BenchmarkCompactBinary2(b *testing.B) { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) - for i := 0; i < b.N; i++ { + for range b.N { ReadWriteBinary(b, p, trans) } } diff --git a/lib/go/thrift/processor_factory.go b/lib/go/thrift/processor_factory.go index 245a3ccfc98..64f89141336 100644 --- a/lib/go/thrift/processor_factory.go +++ b/lib/go/thrift/processor_factory.go @@ -19,7 +19,11 @@ package thrift -import "context" +import ( + "context" + "fmt" + "strings" +) // A processor is a generic object which operates upon an input stream and // writes to some output stream. @@ -78,3 +82,49 @@ func NewTProcessorFunctionFactory(p TProcessorFunction) TProcessorFunctionFactor func (p *tProcessorFunctionFactory) GetProcessorFunction(trans TTransport) TProcessorFunction { return p.processor } + +// ProcessorError is the combined original error returned by the endpoint +// implementation, and I/O error when writing the response back to the client. +// +// This type will be returned by Process function if there's an error happened +// during writing the response back to the client. ProcessorMiddlewares can +// check for this type (use errors.As) to get the underlying write and endpoint +// errors. +type ProcessorError struct { + // WriteError is the error happened during writing the response to the + // client, always set. + WriteError TException + + // EndpointError is the original error returned by the endpoint + // implementation, might be nil. + EndpointError TException +} + +func (pe *ProcessorError) Unwrap() []error { + if pe.EndpointError != nil { + return []error{ + pe.WriteError, + pe.EndpointError, + } + } + return []error{pe.WriteError} +} + +func (pe *ProcessorError) Error() string { + var sb strings.Builder + sb.WriteString("thrift.ProcessorError: ") + sb.WriteString(fmt.Sprintf("write response to client: %v", pe.WriteError)) + if pe.EndpointError != nil { + sb.WriteString(fmt.Sprintf("; original error from endpoint: %v", pe.EndpointError)) + } + return sb.String() +} + +func (pe *ProcessorError) TExceptionType() TExceptionType { + return pe.WriteError.TExceptionType() +} + +var ( + _ error = (*ProcessorError)(nil) + _ TException = (*ProcessorError)(nil) +) diff --git a/lib/go/thrift/protocol.go b/lib/go/thrift/protocol.go index 2ee14caaad1..68cfe4aaa25 100644 --- a/lib/go/thrift/protocol.go +++ b/lib/go/thrift/protocol.go @@ -146,7 +146,7 @@ func Skip(ctx context.Context, self TProtocol, fieldType TType, maxDepth int) (e if err != nil { return err } - for i := 0; i < size; i++ { + for range size { err := Skip(ctx, self, keyType, maxDepth-1) if err != nil { return err @@ -163,7 +163,7 @@ func Skip(ctx context.Context, self TProtocol, fieldType TType, maxDepth int) (e if err != nil { return err } - for i := 0; i < size; i++ { + for range size { err := Skip(ctx, self, elemType, maxDepth-1) if err != nil { return err @@ -175,7 +175,7 @@ func Skip(ctx context.Context, self TProtocol, fieldType TType, maxDepth int) (e if err != nil { return err } - for i := 0; i < size; i++ { + for range size { err := Skip(ctx, self, elemType, maxDepth-1) if err != nil { return err diff --git a/lib/go/thrift/protocol_test.go b/lib/go/thrift/protocol_test.go index 1093c94a969..4fac8013502 100644 --- a/lib/go/thrift/protocol_test.go +++ b/lib/go/thrift/protocol_test.go @@ -45,7 +45,7 @@ var ( func init() { protocol_bdata = make([]byte, PROTOCOL_BINARY_DATA_SIZE) - for i := 0; i < PROTOCOL_BINARY_DATA_SIZE; i++ { + for i := range PROTOCOL_BINARY_DATA_SIZE { protocol_bdata[i] = byte((i + 'a') % 255) } BOOL_VALUES = []bool{false, true, false, false, true} @@ -531,7 +531,7 @@ func ReadWriteBinary(t testing.TB, p TProtocol, trans TTransport) { if len(v) != len(value) { t.Errorf("%s: %T %T len(v) != len(value)... %d != %d", "ReadWriteBinary", p, trans, len(v), len(value)) } else { - for i := 0; i < len(v); i++ { + for i := range v { if v[i] != value[i] { t.Errorf("%s: %T %T %s != %s", "ReadWriteBinary", p, trans, v, value) } diff --git a/lib/go/thrift/serializer_test.go b/lib/go/thrift/serializer_test.go index 425ce0691bc..19879c582d5 100644 --- a/lib/go/thrift/serializer_test.go +++ b/lib/go/thrift/serializer_test.go @@ -328,7 +328,7 @@ func BenchmarkSerializer(b *testing.B) { b.Run( c.Label, func(b *testing.B) { - for i := 0; i < b.N; i++ { + for range b.N { s := c.Serializer() m := MyTestStruct{} str, _ := s.WriteString(context.Background(), &m) diff --git a/lib/go/thrift/serializer_types_test.go b/lib/go/thrift/serializer_types_test.go index 4d1e992ae42..d96001636f6 100644 --- a/lib/go/thrift/serializer_types_test.go +++ b/lib/go/thrift/serializer_types_test.go @@ -319,7 +319,7 @@ func (p *MyTestStruct) readField9(ctx context.Context, iprot TProtocol) error { } tMap := make(map[string]string, size) p.StringMap = tMap - for i := 0; i < size; i++ { + for range size { var _key0 string if v, err := iprot.ReadString(ctx); err != nil { return PrependError("error reading field 0: ", err) @@ -347,7 +347,7 @@ func (p *MyTestStruct) readField10(ctx context.Context, iprot TProtocol) error { } tSlice := make([]string, 0, size) p.StringList = tSlice - for i := 0; i < size; i++ { + for range size { var _elem2 string if v, err := iprot.ReadString(ctx); err != nil { return PrependError("error reading field 0: ", err) @@ -369,7 +369,7 @@ func (p *MyTestStruct) readField11(ctx context.Context, iprot TProtocol) error { } tSet := make(map[string]struct{}, size) p.StringSet = tSet - for i := 0; i < size; i++ { + for range size { var _elem3 string if v, err := iprot.ReadString(ctx); err != nil { return PrependError("error reading field 0: ", err) diff --git a/lib/go/thrift/simple_json_protocol.go b/lib/go/thrift/simple_json_protocol.go index 8b1284fd1b1..ec12991a1d7 100644 --- a/lib/go/thrift/simple_json_protocol.go +++ b/lib/go/thrift/simple_json_protocol.go @@ -30,6 +30,7 @@ import ( "io" "math" "strconv" + "strings" ) type _ParseContext int @@ -922,15 +923,7 @@ func (p *TSimpleJSONProtocol) ParseStringBody() (string, error) { if err != nil { return "", NewTProtocolException(err) } - l := len(line) - // count number of escapes to see if we need to keep going - i := 1 - for ; i < l; i++ { - if line[l-i-1] != '\\' { - break - } - } - if i&0x01 == 1 { + if endsWithoutEscapedQuote(line) { v, ok := jsonUnquote(string(JSON_QUOTE) + line) if !ok { return "", NewTProtocolException(err) @@ -951,27 +944,29 @@ func (p *TSimpleJSONProtocol) ParseStringBody() (string, error) { } func (p *TSimpleJSONProtocol) ParseQuotedStringBody() (string, error) { - line, err := p.reader.ReadString(JSON_QUOTE) - if err != nil { - return "", NewTProtocolException(err) + var sb strings.Builder + + for { + line, err := p.reader.ReadString(JSON_QUOTE) + if err != nil { + return "", NewTProtocolException(err) + } + sb.WriteString(line) + if endsWithoutEscapedQuote(line) { + return sb.String(), nil + } } - l := len(line) - // count number of escapes to see if we need to keep going +} + +func endsWithoutEscapedQuote(s string) bool { + l := len(s) i := 1 for ; i < l; i++ { - if line[l-i-1] != '\\' { + if s[l-i-1] != '\\' { break } } - if i&0x01 == 1 { - return line, nil - } - s, err := p.ParseQuotedStringBody() - if err != nil { - return "", NewTProtocolException(err) - } - v := line + s - return v, nil + return i&0x01 == 1 } func (p *TSimpleJSONProtocol) ParseBase64EncodedBody() ([]byte, error) { @@ -1200,7 +1195,7 @@ func (p *TSimpleJSONProtocol) readNumeric() (Numeric, error) { for continueFor { c, err := p.reader.ReadByte() if err != nil { - if err == io.EOF { + if errors.Is(err, io.EOF) { break } return NUMERIC_NULL, NewTProtocolException(err) @@ -1311,7 +1306,7 @@ func (p *TSimpleJSONProtocol) readNumeric() (Numeric, error) { // Safely peeks into the buffer, reading only what is necessary func (p *TSimpleJSONProtocol) safePeekContains(b []byte) bool { - for i := 0; i < len(b); i++ { + for i := range b { a, _ := p.reader.Peek(i + 1) if len(a) < (i+1) || a[i] != b[i] { return false diff --git a/lib/go/thrift/simple_json_protocol_test.go b/lib/go/thrift/simple_json_protocol_test.go index 89753c6148a..002a2310333 100644 --- a/lib/go/thrift/simple_json_protocol_test.go +++ b/lib/go/thrift/simple_json_protocol_test.go @@ -497,7 +497,7 @@ func TestReadSimpleJSONProtocolBinary(t *testing.T) { if len(v) != len(value) { t.Fatalf("Bad value for %s value length %v, wrote: %v, received length: %v", thetype, len(value), s, len(v)) } - for i := 0; i < len(v); i++ { + for i := range v { if v[i] != value[i] { t.Fatalf("Bad value for %s at index %d value %v, wrote: %v, received: %v", thetype, i, value[i], s, v[i]) } diff --git a/lib/go/thrift/simple_server_test.go b/lib/go/thrift/simple_server_test.go index f3a59ee18ea..0fcb01bd8b8 100644 --- a/lib/go/thrift/simple_server_test.go +++ b/lib/go/thrift/simple_server_test.go @@ -294,6 +294,7 @@ func TestErrAbandonRequest(t *testing.T) { if !errors.Is(ErrAbandonRequest, context.Canceled) { t.Error("errors.Is(ErrAbandonRequest, context.Canceled) returned false") } + //lint:ignore SA1032 Intentional order for this test. if errors.Is(context.Canceled, ErrAbandonRequest) { t.Error("errors.Is(context.Canceled, ErrAbandonRequest) returned true") } diff --git a/lib/go/thrift/socket_aix_syscall.go b/lib/go/thrift/socket_aix_syscall.go new file mode 100644 index 00000000000..2253f753188 --- /dev/null +++ b/lib/go/thrift/socket_aix_syscall.go @@ -0,0 +1,29 @@ +//go:build aix +// +build aix + +/* + * 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 thrift + +import "syscall" + +func peekNonblocking(fd int, p []byte) (int, syscall.Sockaddr, error) { + return syscall.Recvfrom(fd, p, syscall.MSG_PEEK|syscall.MSG_NONBLOCK) +} diff --git a/lib/go/thrift/socket_non_aix_syscall.go b/lib/go/thrift/socket_non_aix_syscall.go new file mode 100644 index 00000000000..523f356dba3 --- /dev/null +++ b/lib/go/thrift/socket_non_aix_syscall.go @@ -0,0 +1,29 @@ +//go:build !aix && !windows && !wasm +// +build !aix,!windows,!wasm + +/* + * 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 thrift + +import "syscall" + +func peekNonblocking(fd int, p []byte) (int, syscall.Sockaddr, error) { + return syscall.Recvfrom(fd, p, syscall.MSG_PEEK|syscall.MSG_DONTWAIT) +} diff --git a/lib/go/thrift/socket_unix_conn.go b/lib/go/thrift/socket_unix_conn.go index ac0dce9e8d2..c06e0e1f6ec 100644 --- a/lib/go/thrift/socket_unix_conn.go +++ b/lib/go/thrift/socket_unix_conn.go @@ -58,7 +58,7 @@ func (sc *socketConn) checkConn() error { var n int if readErr := rc.Read(func(fd uintptr) bool { - n, _, err = syscall.Recvfrom(int(fd), sc.buffer[:], syscall.MSG_PEEK|syscall.MSG_DONTWAIT) + n, _, err = peekNonblocking(int(fd), sc.buffer[:]) return true }); readErr != nil { return readErr diff --git a/lib/go/thrift/ssl_server_socket.go b/lib/go/thrift/ssl_server_socket.go index 907afca326f..3f05ad93db6 100644 --- a/lib/go/thrift/ssl_server_socket.go +++ b/lib/go/thrift/ssl_server_socket.go @@ -93,6 +93,9 @@ func (p *TSSLServerSocket) Open() error { } func (p *TSSLServerSocket) Addr() net.Addr { + if p.listener != nil { + return p.listener.Addr() + } return p.addr } diff --git a/lib/go/thrift/transport_test.go b/lib/go/thrift/transport_test.go index 309cc280507..b6263b8b577 100644 --- a/lib/go/thrift/transport_test.go +++ b/lib/go/thrift/transport_test.go @@ -36,7 +36,7 @@ var ( func init() { transport_bdata = make([]byte, TRANSPORT_BINARY_DATA_SIZE) - for i := 0; i < TRANSPORT_BINARY_DATA_SIZE; i++ { + for i := range TRANSPORT_BINARY_DATA_SIZE { transport_bdata[i] = byte((i + 'a') % 255) } transport_header = map[string]string{"key": "User-Agent", diff --git a/lib/haxe/haxelib.json b/lib/haxe/haxelib.json index 78779da4534..5eabff5f682 100644 --- a/lib/haxe/haxelib.json +++ b/lib/haxe/haxelib.json @@ -10,7 +10,7 @@ "framework" ], "description": "Haxe bindings for the Apache Thrift RPC and serialization framework", - "version": "0.20.0", + "version": "0.22.0", "releasenote": "Licensed under Apache License, Version 2.0. The Apache Thrift compiler needs to be installed separately.", "contributors": ["ApacheThrift"], "dependencies": { diff --git a/lib/haxe/test/Makefile.am b/lib/haxe/test/Makefile.am index 2b8b24524cc..8c658ae7c74 100644 --- a/lib/haxe/test/Makefile.am +++ b/lib/haxe/test/Makefile.am @@ -69,6 +69,9 @@ check: $(BIN_CPP) $(BIN_PHP) $(BIN_CPP) php -f $(BIN_PHP) +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ src \ cpp.hxml \ diff --git a/lib/java/Makefile.am b/lib/java/Makefile.am index 1dd42a7d2ba..fc63af4827f 100644 --- a/lib/java/Makefile.am +++ b/lib/java/Makefile.am @@ -56,6 +56,9 @@ maven-publish: -Pthrift.version=$(PACKAGE_VERSION) \ --console=plain +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ build.gradle \ gradle.properties \ diff --git a/lib/java/README.md b/lib/java/README.md index c65f97ca4f9..8881da66e58 100644 --- a/lib/java/README.md +++ b/lib/java/README.md @@ -42,7 +42,7 @@ The Thrift Java source is not build using the GNU tools, but rather uses the Gradle build system, which tends to be predominant amongst Java developers. -Currently we use gradle 8.0 to build the Thrift Java source. The usual way to setup gradle +Currently we use gradle 8 to build the Thrift Java source. The usual way to setup gradle project is to include the gradle-wrapper.jar in the project and then run the gradle wrapper to bootstrap setting up gradle binaries. However to avoid putting binary files into the source tree we have ignored the gradle wrapper files. You are expected to install it manually, as described in diff --git a/lib/java/build.gradle b/lib/java/build.gradle index 67c4af5cb39..d6be4a7d260 100644 --- a/lib/java/build.gradle +++ b/lib/java/build.gradle @@ -31,7 +31,7 @@ buildscript { } dependencies { - classpath 'com.bmuschko:gradle-clover-plugin:2.2.1' + classpath 'com.bmuschko:gradle-clover-plugin:3.0.7' } } @@ -42,7 +42,7 @@ plugins { id 'pmd' id 'com.github.johnrengelman.shadow' version '8.1.1' id "com.github.spotbugs" version "5.2.5" - id "com.diffplug.spotless" version "6.25.0" + id "com.diffplug.spotless" version "7.0.3" } description = 'Apache Thrift Java Library' diff --git a/lib/java/gradle.properties b/lib/java/gradle.properties index 0d9ff39c364..b1dd36fa85b 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.20.0 +thrift.version=0.22.0 thrift.groupid=org.apache.thrift release=false diff --git a/lib/java/gradle/environment.gradle b/lib/java/gradle/environment.gradle index cbe3fb5a262..368c3e669d8 100644 --- a/lib/java/gradle/environment.gradle +++ b/lib/java/gradle/environment.gradle @@ -71,5 +71,6 @@ dependencies { testImplementation "org.junit.jupiter:junit-jupiter:${junitVersion}" testImplementation "org.mockito:mockito-core:${mockitoVersion}" + testRuntimeOnly "org.junit.platform:junit-platform-launcher" testRuntimeOnly "org.slf4j:slf4j-log4j12:${slf4jVersion}" } diff --git a/lib/java/gradle/unitTests.gradle b/lib/java/gradle/unitTests.gradle index 4f06fcfcdbf..6f63956235b 100644 --- a/lib/java/gradle/unitTests.gradle +++ b/lib/java/gradle/unitTests.gradle @@ -79,7 +79,6 @@ test { maxHeapSize = '512m' systemProperties = [ - 'build.test': "${compileTestJava.destinationDir}", 'test.port': "${testPort}", 'javax.net.ssl.trustStore': "${projectDir}/src/crossTest/resources/.truststore", 'javax.net.ssl.trustStorePassword': 'thrift', diff --git a/lib/java/src/crossTest/java/org/apache/thrift/test/TestTServletServer.java b/lib/java/src/crossTest/java/org/apache/thrift/test/TestTServletServer.java index 574cae64a44..6318c09b752 100644 --- a/lib/java/src/crossTest/java/org/apache/thrift/test/TestTServletServer.java +++ b/lib/java/src/crossTest/java/org/apache/thrift/test/TestTServletServer.java @@ -19,6 +19,7 @@ package org.apache.thrift.test; +import org.apache.catalina.connector.Connector; import org.apache.catalina.core.StandardContext; import org.apache.catalina.startup.Tomcat; import org.apache.catalina.startup.Tomcat.FixContextListener; @@ -30,8 +31,11 @@ public class TestTServletServer { public static void main(String[] args) throws Exception { Tomcat tomcat = new Tomcat(); - tomcat.setPort(port); tomcat.setBaseDir(System.getProperty("user.dir") + "\\build"); + // Add a connector for the tomcat so that it can accept the request + Connector connector = new Connector(); + connector.setPort(port); + tomcat.getService().addConnector(connector); tomcat.getHost().setAutoDeploy(false); String contextPath = "/test"; diff --git a/lib/java/src/main/java/org/apache/thrift/AsyncProcessFunction.java b/lib/java/src/main/java/org/apache/thrift/AsyncProcessFunction.java index c7c4be3036d..4e65ae66e17 100644 --- a/lib/java/src/main/java/org/apache/thrift/AsyncProcessFunction.java +++ b/lib/java/src/main/java/org/apache/thrift/AsyncProcessFunction.java @@ -23,20 +23,22 @@ import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.server.AbstractNonblockingServer; -public abstract class AsyncProcessFunction { +public abstract class AsyncProcessFunction { final String methodName; public AsyncProcessFunction(String methodName) { this.methodName = methodName; } - protected abstract boolean isOneway(); + public abstract boolean isOneway(); public abstract void start(I iface, T args, AsyncMethodCallback resultHandler) throws TException; public abstract T getEmptyArgsInstance(); + public abstract A getEmptyResultInstance(); + public abstract AsyncMethodCallback getResultHandler( final AbstractNonblockingServer.AsyncFrameBuffer fb, int seqid); diff --git a/lib/java/src/main/java/org/apache/thrift/ProcessFunction.java b/lib/java/src/main/java/org/apache/thrift/ProcessFunction.java index 681becaf51d..a1450ae4e82 100644 --- a/lib/java/src/main/java/org/apache/thrift/ProcessFunction.java +++ b/lib/java/src/main/java/org/apache/thrift/ProcessFunction.java @@ -11,7 +11,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public abstract class ProcessFunction { +public abstract class ProcessFunction { private final String methodName; private static final Logger LOGGER = LoggerFactory.getLogger(ProcessFunction.class.getName()); @@ -76,12 +76,15 @@ protected boolean rethrowUnhandledExceptions() { return false; } - protected abstract boolean isOneway(); + public abstract boolean isOneway(); - public abstract TBase getResult(I iface, T args) throws TException; + public abstract TBase getResult(I iface, T args) throws TException; public abstract T getEmptyArgsInstance(); + /** Returns null when this is a oneWay function. */ + public abstract A getEmptyResultInstance(); + public String getMethodName() { return methodName; } diff --git a/lib/java/src/main/java/org/apache/thrift/TBaseAsyncProcessor.java b/lib/java/src/main/java/org/apache/thrift/TBaseAsyncProcessor.java index 266f0c0ceec..eedb8cb5058 100644 --- a/lib/java/src/main/java/org/apache/thrift/TBaseAsyncProcessor.java +++ b/lib/java/src/main/java/org/apache/thrift/TBaseAsyncProcessor.java @@ -30,15 +30,17 @@ public class TBaseAsyncProcessor implements TAsyncProcessor, TProcessor { protected final Logger LOGGER = LoggerFactory.getLogger(getClass().getName()); final I iface; - final Map> processMap; + final Map> processMap; public TBaseAsyncProcessor( - I iface, Map> processMap) { + I iface, + Map> processMap) { this.iface = iface; this.processMap = processMap; } - public Map> getProcessMapView() { + public Map> + getProcessMapView() { return Collections.unmodifiableMap(processMap); } diff --git a/lib/java/src/main/java/org/apache/thrift/TBaseProcessor.java b/lib/java/src/main/java/org/apache/thrift/TBaseProcessor.java index 4038a014a54..49c8cf43a7b 100644 --- a/lib/java/src/main/java/org/apache/thrift/TBaseProcessor.java +++ b/lib/java/src/main/java/org/apache/thrift/TBaseProcessor.java @@ -12,15 +12,16 @@ public abstract class TBaseProcessor implements TProcessor { private final I iface; - private final Map> processMap; + private final Map> processMap; protected TBaseProcessor( - I iface, Map> processFunctionMap) { + I iface, + Map> processFunctionMap) { this.iface = iface; this.processMap = processFunctionMap; } - public Map> getProcessMapView() { + public Map> getProcessMapView() { return Collections.unmodifiableMap(processMap); } diff --git a/lib/java/src/main/java/org/apache/thrift/server/AbstractNonblockingServer.java b/lib/java/src/main/java/org/apache/thrift/server/AbstractNonblockingServer.java index 954aaebf1b5..0388c1104db 100644 --- a/lib/java/src/main/java/org/apache/thrift/server/AbstractNonblockingServer.java +++ b/lib/java/src/main/java/org/apache/thrift/server/AbstractNonblockingServer.java @@ -248,7 +248,7 @@ public class FrameBuffer { protected final TNonblockingTransport trans_; // the SelectionKey that corresponds to our transport - protected final SelectionKey selectionKey_; + protected SelectionKey selectionKey_; // the SelectThread that owns the registration of our transport protected final AbstractSelectThread selectThread_; @@ -302,6 +302,15 @@ public FrameBuffer( } } + /** + * Sets the selection key (this is not thread safe). + * + * @param selectionKey the new key to set. + */ + public void setSelectionKey(SelectionKey selectionKey) { + selectionKey_ = selectionKey; + } + /** * Give this FrameBuffer a chance to read. The selector loop should have received a read event * for this FrameBuffer. @@ -375,7 +384,11 @@ public boolean read() { // modify our selection key directly. if (buffer_.remaining() == 0) { // get rid of the read select interests - selectionKey_.interestOps(0); + if (selectionKey_.isValid()) { + selectionKey_.interestOps(0); + } else { + LOGGER.warn("SelectionKey was invalidated during read"); + } state_ = FrameBufferState.READ_FRAME_COMPLETE; } @@ -415,8 +428,12 @@ public void changeSelectInterests() { switch (state_) { case AWAITING_REGISTER_WRITE: // set the OP_WRITE interest - selectionKey_.interestOps(SelectionKey.OP_WRITE); - state_ = FrameBufferState.WRITING; + if (selectionKey_.isValid()) { + selectionKey_.interestOps(SelectionKey.OP_WRITE); + state_ = FrameBufferState.WRITING; + } else { + LOGGER.warn("SelectionKey was invalidated before write"); + } break; case AWAITING_REGISTER_READ: prepareRead(); @@ -520,7 +537,11 @@ private boolean internalRead() { private void prepareRead() { // we can set our interest directly without using the queue because // we're in the select thread. - selectionKey_.interestOps(SelectionKey.OP_READ); + if (selectionKey_.isValid()) { + selectionKey_.interestOps(SelectionKey.OP_READ); + } else { + LOGGER.warn("SelectionKey was invalidated before read"); + } // get ready for another go-around buffer_ = ByteBuffer.allocate(4); state_ = FrameBufferState.READING_FRAME_SIZE; diff --git a/lib/java/src/main/java/org/apache/thrift/server/TSaslNonblockingServer.java b/lib/java/src/main/java/org/apache/thrift/server/TSaslNonblockingServer.java index 6f22d8bb454..8c899d56cdb 100644 --- a/lib/java/src/main/java/org/apache/thrift/server/TSaslNonblockingServer.java +++ b/lib/java/src/main/java/org/apache/thrift/server/TSaslNonblockingServer.java @@ -255,7 +255,7 @@ private void handleIO() { } else if (selected.isWritable()) { saslHandler.handleWrite(); } else { - LOGGER.error("Invalid intrest op " + selected.interestOps()); + LOGGER.error("Invalid interest op " + selected.interestOps()); closeChannel(selected); continue; } diff --git a/lib/java/src/main/java/org/apache/thrift/server/TThreadPoolServer.java b/lib/java/src/main/java/org/apache/thrift/server/TThreadPoolServer.java index 06fdeec9ca1..5409034a918 100644 --- a/lib/java/src/main/java/org/apache/thrift/server/TThreadPoolServer.java +++ b/lib/java/src/main/java/org/apache/thrift/server/TThreadPoolServer.java @@ -277,7 +277,7 @@ public void run() { private void logException(Exception x) { // We'll usually receive RuntimeException types here // Need to unwrap to ascertain real causing exception before we choose to ignore - // Ignoring err-logging all transport-level/type exceptions and SocketExceptions + LOGGER.debug("Error processing request", x); TTransportException tTransportException = null; if (x instanceof TTransportException) { @@ -292,8 +292,7 @@ private void logException(Exception x) { case TTransportException.TIMED_OUT: return; // don't log these } - if (tTransportException.getCause() != null - && (tTransportException.getCause() instanceof SocketException)) { + if (tTransportException.getCause() instanceof SocketException) { LOGGER.warn( "SocketException occurred during processing of message.", tTransportException.getCause()); diff --git a/lib/java/src/main/java/org/apache/thrift/server/TThreadedSelectorServer.java b/lib/java/src/main/java/org/apache/thrift/server/TThreadedSelectorServer.java index 86b8dfd2337..33b4686ded7 100644 --- a/lib/java/src/main/java/org/apache/thrift/server/TThreadedSelectorServer.java +++ b/lib/java/src/main/java/org/apache/thrift/server/TThreadedSelectorServer.java @@ -626,16 +626,23 @@ private synchronized void rebuildSelector() { LOGGER.error("Create new Selector error.", e); } - for (SelectionKey key : oldSelector.selectedKeys()) { - if (!key.isValid() && key.readyOps() == 0) continue; + for (SelectionKey key : oldSelector.keys()) { + if (!key.isValid() || key.interestOps() == 0 || key.channel().keyFor(newSelector) != null) { + continue; + } SelectableChannel channel = key.channel(); Object attachment = key.attachment(); + int interestOps = key.interestOps(); + SelectionKey newKey; try { if (attachment == null) { - channel.register(newSelector, key.readyOps()); + newKey = channel.register(newSelector, interestOps); } else { - channel.register(newSelector, key.readyOps(), attachment); + newKey = channel.register(newSelector, interestOps, attachment); + if (attachment instanceof FrameBuffer) { + ((FrameBuffer) attachment).setSelectionKey(newKey); + } } } catch (ClosedChannelException e) { LOGGER.error("Register new selector key error.", e); diff --git a/lib/java/src/main/java/org/apache/thrift/transport/TEndpointTransport.java b/lib/java/src/main/java/org/apache/thrift/transport/TEndpointTransport.java index 72bf9539180..6026390413c 100644 --- a/lib/java/src/main/java/org/apache/thrift/transport/TEndpointTransport.java +++ b/lib/java/src/main/java/org/apache/thrift/transport/TEndpointTransport.java @@ -65,7 +65,9 @@ protected void resetConsumedMessageSize(long newSize) throws TTransportException // update only: message size can shrink, but not grow if (newSize > knownMessageSize) - throw new TTransportException(TTransportException.END_OF_FILE, "MaxMessageSize reached"); + throw new TTransportException( + TTransportException.MESSAGE_SIZE_LIMIT, + "Message size exceeds limit: " + getMaxMessageSize()); knownMessageSize = newSize; remainingMessageSize = newSize; @@ -91,7 +93,9 @@ public void updateKnownMessageSize(long size) throws TTransportException { */ public void checkReadBytesAvailable(long numBytes) throws TTransportException { if (remainingMessageSize < numBytes) - throw new TTransportException(TTransportException.END_OF_FILE, "MaxMessageSize reached"); + throw new TTransportException( + TTransportException.MESSAGE_SIZE_LIMIT, + "Message size exceeds limit: " + getMaxMessageSize()); } /** @@ -104,7 +108,9 @@ protected void countConsumedMessageBytes(long numBytes) throws TTransportExcepti remainingMessageSize -= numBytes; } else { remainingMessageSize = 0; - throw new TTransportException(TTransportException.END_OF_FILE, "MaxMessageSize reached"); + throw new TTransportException( + TTransportException.MESSAGE_SIZE_LIMIT, + "Message size exceeds limit: " + getMaxMessageSize()); } } } diff --git a/lib/java/src/main/java/org/apache/thrift/transport/TTransportException.java b/lib/java/src/main/java/org/apache/thrift/transport/TTransportException.java index cc7532f2ad1..a7ebed6e32d 100644 --- a/lib/java/src/main/java/org/apache/thrift/transport/TTransportException.java +++ b/lib/java/src/main/java/org/apache/thrift/transport/TTransportException.java @@ -32,6 +32,7 @@ public class TTransportException extends TException { public static final int TIMED_OUT = 3; public static final int END_OF_FILE = 4; public static final int CORRUPTED_DATA = 5; + public static final int MESSAGE_SIZE_LIMIT = 6; protected int type_ = UNKNOWN; diff --git a/lib/java/src/test/java/org/apache/thrift/protocol/ProtocolTestBase.java b/lib/java/src/test/java/org/apache/thrift/protocol/ProtocolTestBase.java index 8a5d214d6ae..51fd1651d7b 100644 --- a/lib/java/src/test/java/org/apache/thrift/protocol/ProtocolTestBase.java +++ b/lib/java/src/test/java/org/apache/thrift/protocol/ProtocolTestBase.java @@ -554,7 +554,7 @@ public void testReadCheckMaxMessageRequestForString() throws TException { String result = testClient.recv_testString(); System.out.println("----result: " + result); } catch (TException e) { - assertEquals("MaxMessageSize reached", e.getMessage()); + assertEquals(TTransportException.MESSAGE_SIZE_LIMIT, ((TTransportException) e).getType()); } } @@ -573,7 +573,7 @@ public void testReadCheckMaxMessageRequestForList() throws TException { testClient.recv_testList(); }, "Limitations not achieved as expected"); - assertEquals("MaxMessageSize reached", e.getMessage()); + assertEquals(TTransportException.MESSAGE_SIZE_LIMIT, e.getType()); } @Test @@ -595,7 +595,7 @@ public void testReadCheckMaxMessageRequestForMap() throws TException { }, "Limitations not achieved as expected"); - assertEquals("MaxMessageSize reached", e.getMessage()); + assertEquals(TTransportException.MESSAGE_SIZE_LIMIT, e.getType()); } @Test @@ -614,6 +614,6 @@ public void testReadCheckMaxMessageRequestForSet() throws TException { testClient.recv_testSet(); }, "Limitations not achieved as expected"); - assertEquals("MaxMessageSize reached", e.getMessage()); + assertEquals(TTransportException.MESSAGE_SIZE_LIMIT, e.getType()); } } diff --git a/lib/java/src/test/java/org/apache/thrift/test/EqualityTest.java b/lib/java/src/test/java/org/apache/thrift/test/EqualityTest.java index fee495ca762..02a14d07eec 100644 --- a/lib/java/src/test/java/org/apache/thrift/test/EqualityTest.java +++ b/lib/java/src/test/java/org/apache/thrift/test/EqualityTest.java @@ -20,10 +20,7 @@ /* This program was generated by the following Python script: -#!/usr/bin/python2.5 - -# Remove this when Python 2.6 hits the streets. -from __future__ import with_statement +#!/usr/bin/python3 import sys import os.path diff --git a/lib/java/src/test/java/org/apache/thrift/transport/TestTByteBuffer.java b/lib/java/src/test/java/org/apache/thrift/transport/TestTByteBuffer.java index 26ffc5d58f3..163186a601a 100644 --- a/lib/java/src/test/java/org/apache/thrift/transport/TestTByteBuffer.java +++ b/lib/java/src/test/java/org/apache/thrift/transport/TestTByteBuffer.java @@ -52,7 +52,7 @@ public void testSmallTConfiguration() throws Exception { assertThrows( TTransportException.class, () -> new TByteBuffer(configSmall, ByteBuffer.allocate(100))); - assertEquals("MaxMessageSize reached", e.getMessage()); + assertEquals(TTransportException.MESSAGE_SIZE_LIMIT, e.getType()); } @Test diff --git a/lib/js/Gruntfile.js b/lib/js/Gruntfile.js index 97713140a25..089ef8f6610 100644 --- a/lib/js/Gruntfile.js +++ b/lib/js/Gruntfile.js @@ -5,47 +5,48 @@ // 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'; +module.exports = function (grunt) { + "use strict"; grunt.initConfig({ - pkg: grunt.file.readJSON('package.json'), + pkg: grunt.file.readJSON("package.json"), concat: { options: { - separator: ';' + separator: ";", }, dist: { - src: ['src/**/*.js'], - dest: 'dist/<%= pkg.name %>.js' - } + src: ["src/**/*.js"], + dest: "dist/<%= pkg.name %>.js", + }, }, - jsdoc : { - dist : { - src: ['src/*.js', './README.md'], - options: { - destination: 'doc' - } - } + jsdoc: { + dist: { + src: ["src/*.js", "./README.md"], + options: { + destination: "doc", + }, + }, }, uglify: { options: { - banner: '/*! <%= pkg.name %> <%= grunt.template.today("dd-mm-yyyy") %> */\n' + banner: + '/*! <%= pkg.name %> <%= grunt.template.today("dd-mm-yyyy") %> */\n', }, dist: { files: { - 'dist/<%= pkg.name %>.min.js': ['<%= concat.dist.dest %>'] - } - } + "dist/<%= pkg.name %>.min.js": ["<%= concat.dist.dest %>"], + }, + }, }, shell: { InstallThriftJS: { - command: 'cp src/thrift.js test/build/js/thrift.js' + command: "cp src/thrift.js test/build/js/thrift.js", }, InstallThriftNodeJSDep: { - command: 'cd ../.. && npm install' + command: "cd ../.. && npm install", }, InstallTestLibs: { - command: 'cd test && ant download_jslibs' + command: "cd test && ant download_jslibs", }, ThriftGen: { command: [ @@ -55,34 +56,38 @@ module.exports = function(grunt) { '"../../compiler/cpp/thrift" -gen js:node --out test/gen-nodejs ../../test/v0.16/ThriftTest.thrift', '"../../compiler/cpp/thrift" -gen js:es6 --out test/gen-js-es6 ../../test/v0.16/ThriftTest.thrift', '"../../compiler/cpp/thrift" -gen js:node,es6 --out ./test/gen-nodejs-es6 ../../test/v0.16/ThriftTest.thrift', - ].join(' && ') + ].join(" && "), }, ThriftGenJQ: { - command: '../../compiler/cpp/thrift -gen js:jquery -gen js:node -o test ../../test/v0.16/ThriftTest.thrift' + command: + "../../compiler/cpp/thrift -gen js:jquery -gen js:node -o test ../../test/v0.16/ThriftTest.thrift", }, ThriftGenDeepConstructor: { - command: '../../compiler/cpp/thrift -gen js -o test ../../test/JsDeepConstructorTest.thrift' + 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(' && ') + "./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' + command: + "../../compiler/cpp/thrift -gen js -o test ../../test/Int64Test.thrift", }, ThriftGenDoubleConstants: { - command: '../../compiler/cpp/thrift -gen js -o test ../../test/DoubleConstantsTest.thrift' + command: + "../../compiler/cpp/thrift -gen js -o test ../../test/DoubleConstantsTest.thrift", }, ThriftTestServer: { options: { async: true, execOptions: { cwd: "./test", - env: {NODE_PATH: "../../nodejs/lib:../../../node_modules"} - } + env: { NODE_PATH: "../../nodejs/lib:../../../node_modules" }, + }, }, command: "node server_http.js", }, @@ -91,8 +96,8 @@ module.exports = function(grunt) { async: true, execOptions: { cwd: "./test", - env: {NODE_PATH: "../../nodejs/lib:../../../node_modules"} - } + env: { NODE_PATH: "../../nodejs/lib:../../../node_modules" }, + }, }, command: "node server_http.js --es6", }, @@ -101,8 +106,8 @@ module.exports = function(grunt) { async: true, execOptions: { cwd: "./test", - env: {NODE_PATH: "../../nodejs/lib:../../../node_modules"} - } + env: { NODE_PATH: "../../nodejs/lib:../../../node_modules" }, + }, }, command: "node server_https.js", }, @@ -111,8 +116,8 @@ module.exports = function(grunt) { async: true, execOptions: { cwd: "./test", - env: {NODE_PATH: "../../nodejs/lib:../../../node_modules"} - } + env: { NODE_PATH: "../../nodejs/lib:../../../node_modules" }, + }, }, command: "node server_https.js --es6", }, @@ -120,213 +125,201 @@ module.exports = function(grunt) { qunit: { ThriftJS: { options: { - urls: [ - 'http://localhost:8089/test-nojq.html' - ], + urls: ["http://localhost:8089/test-nojq.html"], puppeteer: { headless: true, - args: ['--no-sandbox'], + args: ["--no-sandbox"], }, - } + }, }, ThriftJSJQ: { options: { - urls: [ - 'http://localhost:8089/test.html' - ], + urls: ["http://localhost:8089/test.html"], puppeteer: { headless: true, - args: ['--no-sandbox'], + args: ["--no-sandbox"], }, - } + }, }, ThriftJS_DoubleRendering: { options: { - urls: [ - 'http://localhost:8089/test-double-rendering.html' - ], + urls: ["http://localhost:8089/test-double-rendering.html"], puppeteer: { headless: true, - args: ['--no-sandbox'], + args: ["--no-sandbox"], ignoreHTTPSErrors: true, }, - } + }, }, ThriftJS_Int64: { options: { - urls: [ - 'http://localhost:8089/test-int64.html' - ], + urls: ["http://localhost:8089/test-int64.html"], puppeteer: { headless: true, - args: ['--no-sandbox'], + args: ["--no-sandbox"], ignoreHTTPSErrors: true, }, - } + }, }, ThriftWS: { options: { - urls: [ - 'http://localhost:8089/testws.html' - ], + urls: ["http://localhost:8089/testws.html"], puppeteer: { headless: true, - args: ['--no-sandbox'], + args: ["--no-sandbox"], }, - } + }, }, ThriftJS_TLS: { options: { - urls: [ - 'https://localhost:8091/test-nojq.html' - ], + urls: ["https://localhost:8091/test-nojq.html"], puppeteer: { headless: true, - args: ['--no-sandbox'], + args: ["--no-sandbox"], ignoreHTTPSErrors: true, }, - } + }, }, ThriftJSJQ_TLS: { options: { - urls: [ - 'https://localhost:8091/test.html' - ], + urls: ["https://localhost:8091/test.html"], puppeteer: { headless: true, - args: ['--no-sandbox'], + args: ["--no-sandbox"], ignoreHTTPSErrors: true, }, - } + }, }, ThriftWS_TLS: { options: { - urls: [ - 'https://localhost:8091/testws.html' - ], + urls: ["https://localhost:8091/testws.html"], puppeteer: { headless: true, - args: ['--no-sandbox'], + args: ["--no-sandbox"], ignoreHTTPSErrors: true, }, - } + }, }, ThriftDeepConstructor: { options: { - urls: [ - 'http://localhost:8089/test-deep-constructor.html' - ], + urls: ["http://localhost:8089/test-deep-constructor.html"], puppeteer: { headless: true, - args: ['--no-sandbox'], + args: ["--no-sandbox"], }, - } + }, }, ThriftWSES6: { options: { - urls: [ - 'http://localhost:8088/test-es6.html' - ], + urls: ["http://localhost:8088/test-es6.html"], puppeteer: { headless: true, - args: ['--no-sandbox'], + args: ["--no-sandbox"], }, - } - } + }, + }, }, jshint: { // The main Thrift library file. not es6 yet :( lib: { - src: ['src/**/*.js'], + src: ["src/**/*.js"], }, // The test files use es6 test: { - src: ['Gruntfile.js', 'test/*.js'], + src: ["Gruntfile.js", "test/*.js"], options: { esversion: 6, - } + }, }, gen_js_code: { - src: ['test/gen-js/*.js', 'test/gen-js-jquery/*.js'], + src: ["test/gen-js/*.js", "test/gen-js-jquery/*.js"], }, gen_es6_code: { - src: ['test/gen-js-es6/*.js'], + src: ["test/gen-js-es6/*.js"], options: { esversion: 6, - } + }, }, gen_node_code: { - src: ['test/gen-nodejs/*.js'], + src: ["test/gen-nodejs/*.js"], options: { node: true, - } + }, }, gen_node_es6_code: { - src: ['test/gen-nodejs-es6/*.js'], + src: ["test/gen-nodejs-es6/*.js"], options: { node: true, esversion: 6, - } - } + }, + }, }, }); - grunt.loadNpmTasks('grunt-contrib-uglify'); - grunt.loadNpmTasks('grunt-contrib-jshint'); - grunt.loadNpmTasks('grunt-contrib-qunit'); - grunt.loadNpmTasks('grunt-contrib-concat'); - grunt.loadNpmTasks('grunt-jsdoc'); - grunt.loadNpmTasks('grunt-shell-spawn'); + grunt.loadNpmTasks("grunt-contrib-uglify"); + grunt.loadNpmTasks("grunt-contrib-jshint"); + grunt.loadNpmTasks("grunt-contrib-qunit"); + grunt.loadNpmTasks("grunt-contrib-concat"); + grunt.loadNpmTasks("grunt-jsdoc"); + 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( + "wait", + "Wait just one second for the server to start", + function () { + var done = this.async(); + setTimeout(function () { + done(true); + }, 1000); + }, + ); - grunt.registerTask('CreateDirectories', 'Creating required local directories', function () { - grunt.file.mkdir('test/build/js/lib'); - grunt.file.mkdir('test/gen-js'); - grunt.file.mkdir('test/gen-js-jquery'); - grunt.file.mkdir('test/gen-nodejs'); - grunt.file.mkdir('test/gen-js-es6'); - grunt.file.mkdir('test/gen-nodejs-es6'); -}); + grunt.registerTask( + "CreateDirectories", + "Creating required local directories", + function () { + grunt.file.mkdir("test/build/js/lib"); + grunt.file.mkdir("test/gen-js"); + grunt.file.mkdir("test/gen-js-jquery"); + grunt.file.mkdir("test/gen-nodejs"); + grunt.file.mkdir("test/gen-js-es6"); + grunt.file.mkdir("test/gen-nodejs-es6"); + }, + ); - grunt.registerTask('installAndGenerate', [ - 'CreateDirectories', - 'shell:InstallThriftJS', - 'shell:InstallThriftNodeJSDep', - 'shell:ThriftGen', - 'shell:ThriftGenDeepConstructor', - 'shell:ThriftGenDoubleConstants', - 'shell:InstallTestLibs', - 'shell:ThriftBrowserifyNodeInt64', - 'shell:ThriftGenInt64' + grunt.registerTask("installAndGenerate", [ + "CreateDirectories", + "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', - 'wait', - 'qunit:ThriftDeepConstructor', - 'qunit:ThriftJS', - 'qunit:ThriftJS_TLS', - 'qunit:ThriftJS_DoubleRendering', - 'qunit:ThriftWS', - 'qunit:ThriftJSJQ', - 'qunit:ThriftJSJQ_TLS', - 'qunit:ThriftWSES6', - 'qunit:ThriftJS_Int64', - 'shell:ThriftTestServer:kill', - 'shell:ThriftTestServer_TLS:kill', - 'shell:ThriftTestServerES6:kill', - 'shell:ThriftTestServerES6_TLS:kill', + grunt.registerTask("test", [ + "installAndGenerate", + "jshint", + "shell:ThriftTestServer", + "shell:ThriftTestServer_TLS", + "shell:ThriftTestServerES6", + "shell:ThriftTestServerES6_TLS", + "wait", + "qunit:ThriftDeepConstructor", + "qunit:ThriftJS", + "qunit:ThriftJS_TLS", + "qunit:ThriftJS_DoubleRendering", + "qunit:ThriftWS", + "qunit:ThriftJSJQ", + "qunit:ThriftJSJQ_TLS", + "qunit:ThriftWSES6", + "qunit:ThriftJS_Int64", + "shell:ThriftTestServer:kill", + "shell:ThriftTestServer_TLS:kill", + "shell:ThriftTestServerES6:kill", + "shell:ThriftTestServerES6_TLS:kill", ]); - grunt.registerTask('default', ['test', 'concat', 'uglify', 'jsdoc']); + grunt.registerTask("default", ["test", "concat", "uglify", "jsdoc"]); }; diff --git a/lib/js/Makefile.am b/lib/js/Makefile.am index 4906d7ddbcc..9b7dfb6d30f 100644 --- a/lib/js/Makefile.am +++ b/lib/js/Makefile.am @@ -52,6 +52,9 @@ dist-hook: $(RM) -r $(distdir)/test/build/ $(RM) -r $(distdir)/test/gen-*/ +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ coding_standards.md \ Gruntfile.js \ diff --git a/lib/js/package-lock.json b/lib/js/package-lock.json index 0d9de1242b8..cb202ca75e2 100644 --- a/lib/js/package-lock.json +++ b/lib/js/package-lock.json @@ -1,12 +1,12 @@ { "name": "thrift", - "version": "0.20.0", + "version": "0.22.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "thrift", - "version": "0.20.0", + "version": "0.22.0", "license": "Apache-2.0", "devDependencies": { "browserify": "~16.5", @@ -235,12 +235,12 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -1060,10 +1060,11 @@ } }, "node_modules/elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "version": "6.6.1", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.6.1.tgz", + "integrity": "sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==", "dev": true, + "license": "MIT", "dependencies": { "bn.js": "^4.11.9", "brorand": "^1.1.0", @@ -1225,9 +1226,9 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "dependencies": { "to-regex-range": "^5.0.1" @@ -3926,9 +3927,9 @@ "dev": true }, "node_modules/ws": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", - "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.3.tgz", + "integrity": "sha512-jmTjYU0j60B+vHey6TfR3Z7RD61z/hmxBS3VMSGIrroOWXQEneK1zNuotOUrGyBHQj0yrpsLHPWtigEFd13ndA==", "dev": true, "dependencies": { "async-limiter": "~1.0.0" diff --git a/lib/js/package.json b/lib/js/package.json index 8543b2500c4..73a8cb450bc 100644 --- a/lib/js/package.json +++ b/lib/js/package.json @@ -1,6 +1,6 @@ { "name": "thrift", - "version": "0.20.0", + "version": "0.22.0", "description": "Thrift is a software framework for scalable cross-language services development.", "main": "./src/thrift", "author": { diff --git a/lib/js/src/thrift.js b/lib/js/src/thrift.js index 7dbb560c740..7a23eac4d2b 100644 --- a/lib/js/src/thrift.js +++ b/lib/js/src/thrift.js @@ -46,7 +46,7 @@ var Thrift = { * @const {string} Version * @memberof Thrift */ - Version: '0.20.0', + Version: '0.22.0', /** * Thrift IDL type string to Id mapping. diff --git a/lib/js/test/Makefile.am b/lib/js/test/Makefile.am index 14927c40a51..8a817b36621 100644 --- a/lib/js/test/Makefile.am +++ b/lib/js/test/Makefile.am @@ -24,6 +24,9 @@ clean-local: ANT=$(ANT) ; if test -z "$$ANT" ; then ANT=: ; fi ; \ $$ANT $(ANT_FLAGS) clean +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + check-local: all $(ANT) $(ANT_FLAGS) test diff --git a/lib/json/Makefile.am b/lib/json/Makefile.am index 6c8c0ce8116..3c7aa8f3d74 100644 --- a/lib/json/Makefile.am +++ b/lib/json/Makefile.am @@ -28,6 +28,9 @@ clean-local: dist-hook: $(RM) -r $(distdir)/test/build/ +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ schema.json \ test diff --git a/lib/json/schema.json b/lib/json/schema.json index f7b10dff437..e2b997745c9 100644 --- a/lib/json/schema.json +++ b/lib/json/schema.json @@ -64,7 +64,7 @@ "required": [ "typeId", "keyTypeId", "valueTypeId" ] }, "struct-type": { - "title": "Struct, union and exception schema", + "title": "Struct, union, enum and exception schema", "type": "object", "properties": { "typeId": { @@ -145,9 +145,9 @@ "type": "object", "allOf": [ { "$ref": "#/definitions/name-and-doc" }, - { "$ref": "#/definitions/type-desc" }, { "properties": { + "type": { "$ref": "#/definitions/type-desc" }, "value": { "oneOf": [ { "type": "string" }, diff --git a/lib/json/test/Makefile.am b/lib/json/test/Makefile.am index bb87a52038f..16bcfae383f 100644 --- a/lib/json/test/Makefile.am +++ b/lib/json/test/Makefile.am @@ -20,6 +20,9 @@ check: $(ANT) $(ANT_FLAGS) test +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + # Make sure this doesn't fail if ant is not configured. clean-local: ANT=$(ANT) ; if test -z "$$ANT" ; then ANT=: ; fi ; \ diff --git a/lib/kotlin/Makefile.am b/lib/kotlin/Makefile.am index 720f8234fe0..e5685cf7162 100644 --- a/lib/kotlin/Makefile.am +++ b/lib/kotlin/Makefile.am @@ -40,6 +40,9 @@ check-local: $(THRIFT) -Pthrift.compiler=$(THRIFT) \ --console=plain +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ build.gradle.kts \ CMakeLists.txt \ diff --git a/lib/kotlin/build.gradle.kts b/lib/kotlin/build.gradle.kts index 5c9929bd987..cf2880bada5 100644 --- a/lib/kotlin/build.gradle.kts +++ b/lib/kotlin/build.gradle.kts @@ -16,6 +16,8 @@ * specific language governing permissions and limitations * under the License. */ +import org.jetbrains.kotlin.gradle.dsl.JvmTarget +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { kotlin("jvm") @@ -29,19 +31,27 @@ repositories { dependencies { implementation(platform("org.jetbrains.kotlin:kotlin-bom")) implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") - implementation("org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:1.7.3") + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:1.10.2") implementation("org.apache.thrift:libthrift:INCLUDED") testImplementation(kotlin("test")) } kotlin { jvmToolchain { - (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(8)) + languageVersion.set(JavaLanguageVersion.of(17)) } } -tasks.withType { - kotlinOptions.jvmTarget = "1.8" +java { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 +} + +tasks.withType { + compilerOptions { + jvmTarget = JvmTarget.JVM_1_8 + freeCompilerArgs = listOf("-Xjdk-release=1.8") + } } tasks { diff --git a/lib/kotlin/cross-test-client/build.gradle.kts b/lib/kotlin/cross-test-client/build.gradle.kts index 8a2c234b823..c68f393ac26 100644 --- a/lib/kotlin/cross-test-client/build.gradle.kts +++ b/lib/kotlin/cross-test-client/build.gradle.kts @@ -50,12 +50,6 @@ dependencies { testImplementation("org.jetbrains.kotlin:kotlin-test-junit") } -kotlin { - jvmToolchain { - (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(8)) - } -} - tasks { application { applicationName = "TestClient" diff --git a/lib/kotlin/cross-test-client/src/main/kotlin/org/apache/thrift/test/TestClient.kt b/lib/kotlin/cross-test-client/src/main/kotlin/org/apache/thrift/test/TestClient.kt index c238d0b426e..5178b55afed 100644 --- a/lib/kotlin/cross-test-client/src/main/kotlin/org/apache/thrift/test/TestClient.kt +++ b/lib/kotlin/cross-test-client/src/main/kotlin/org/apache/thrift/test/TestClient.kt @@ -66,14 +66,14 @@ enum class ProtocolType(val key: String) { Json("json"), MultiJson("multij"), Compact("compact"), - MultiCompact("multic") + MultiCompact("multic"), } enum class TransportType(val key: String) { Buffered("buffered"), Framed("framed"), FastFramed("fastframed"), - Http("http") + Http("http"), } class TestClient : CliktCommand() { @@ -438,7 +438,7 @@ class TestClient : CliktCommand() { private suspend fun exceptionTest( testClient: ThriftTestClient, - returnCode: Int + returnCode: Int, ): Pair { var client = testClient var code = returnCode @@ -473,7 +473,7 @@ class TestClient : CliktCommand() { private suspend fun multiExceptionTest( testClient: ThriftTestClient, - returnCode: Int + returnCode: Int, ): Pair { var client = testClient var code = returnCode diff --git a/lib/kotlin/cross-test-server/build.gradle.kts b/lib/kotlin/cross-test-server/build.gradle.kts index eda1ebd0c39..57fef4f66d0 100644 --- a/lib/kotlin/cross-test-server/build.gradle.kts +++ b/lib/kotlin/cross-test-server/build.gradle.kts @@ -48,12 +48,6 @@ dependencies { testImplementation("org.jetbrains.kotlin:kotlin-test-junit") } -kotlin { - jvmToolchain { - (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(8)) - } -} - tasks { application { applicationName = "TestServer" @@ -68,7 +62,7 @@ tasks { task("compileThrift") { val thriftBin = if (hasProperty("thrift.compiler")) { - file(property("thrift.compiler")) + file(property("thrift.compiler")!!) } else { project.rootDir.resolve("../../compiler/cpp/thrift") } diff --git a/lib/kotlin/cross-test-server/src/main/kotlin/org/apache/thrift/test/TestHandler.kt b/lib/kotlin/cross-test-server/src/main/kotlin/org/apache/thrift/test/TestHandler.kt index b7f38d7fe53..425d46b6fcb 100644 --- a/lib/kotlin/cross-test-server/src/main/kotlin/org/apache/thrift/test/TestHandler.kt +++ b/lib/kotlin/cross-test-server/src/main/kotlin/org/apache/thrift/test/TestHandler.kt @@ -104,7 +104,8 @@ class TestHandler : ThriftTest { override suspend fun testNest(thing: Xtruct2): Xtruct2 { val thing2: Xtruct = thing.struct_thing!! logger.info( - """testNest({${thing.byte_thing}, {"${thing2.string_thing}", ${thing2.byte_thing}, ${thing2.i32_thing}, ${thing2.i64_thing}}, ${thing.i32_thing}})""".trimIndent() + """testNest({${thing.byte_thing}, {"${thing2.string_thing}", ${thing2.byte_thing}, ${thing2.i32_thing}, ${thing2.i64_thing}}, ${thing.i32_thing}})""" + .trimIndent() ) return thing } @@ -201,7 +202,7 @@ class TestHandler : ThriftTest { arg2: Long, arg3: Map, arg4: Numberz, - arg5: Long + arg5: Long, ): Xtruct { logger.info("testMulti()\n") val hello = Xtruct() diff --git a/lib/kotlin/cross-test-server/src/main/kotlin/org/apache/thrift/test/TestServer.kt b/lib/kotlin/cross-test-server/src/main/kotlin/org/apache/thrift/test/TestServer.kt index 315d12e722d..706083faf0e 100644 --- a/lib/kotlin/cross-test-server/src/main/kotlin/org/apache/thrift/test/TestServer.kt +++ b/lib/kotlin/cross-test-server/src/main/kotlin/org/apache/thrift/test/TestServer.kt @@ -96,6 +96,7 @@ object TestServer { internal class TestServerEventHandler() : TServerEventHandler { private var nextConnectionId = 1 + override fun preServe() { println( "TServerEventHandler.preServe - called only once before server starts accepting connections" @@ -117,7 +118,7 @@ object TestServer { override fun deleteContext( serverContext: ServerContext, input: TProtocol, - output: TProtocol + output: TProtocol, ) { val ctx = serverContext.unwrap(TestServerContext::class.java) println( @@ -130,7 +131,7 @@ object TestServer { override fun processContext( serverContext: ServerContext, inputTransport: TTransport, - outputTransport: TTransport + outputTransport: TTransport, ) { val ctx = serverContext.unwrap(TestServerContext::class.java) println( @@ -146,7 +147,7 @@ enum class ServerType(val key: String) { Simple("simple"), ThreadPool("thread-pool"), NonBlocking("nonblocking"), - ThreadedSelector("threaded-selector") + ThreadedSelector("threaded-selector"), } enum class ProtocolType(val key: String) { @@ -155,14 +156,14 @@ enum class ProtocolType(val key: String) { Json("json"), MultiJson("multij"), Compact("compact"), - MultiCompact("multic") + MultiCompact("multic"), } enum class TransportType(val key: String) { Buffered("buffered"), FastFramed("fastframed"), Framed("framed"), - Zlib("zlib") + Zlib("zlib"), } class TestServerCommand : CliktCommand() { @@ -197,7 +198,7 @@ class TestServerCommand : CliktCommand() { protocolType, getProtocolFactory(), getTransportFactory(), - useSSL + useSSL, ) // Set server event handler serverEngine.setServerEventHandler(TestServer.TestServerEventHandler()) @@ -247,7 +248,7 @@ private fun getServerEngine( protocolType: ProtocolType, tProtocolFactory: TProtocolFactory, tTransportFactory: TTransportFactory, - ssl: Boolean + ssl: Boolean, ): TServer { val isMulti = protocolType == ProtocolType.Multi || diff --git a/lib/kotlin/settings.gradle.kts b/lib/kotlin/settings.gradle.kts index 294cd83c1d6..2311a730883 100644 --- a/lib/kotlin/settings.gradle.kts +++ b/lib/kotlin/settings.gradle.kts @@ -18,8 +18,8 @@ */ pluginManagement { plugins { - kotlin("jvm") version "1.9.22" - id("com.ncorti.ktfmt.gradle") version "0.12.0" + kotlin("jvm") version "2.1.20" + id("com.ncorti.ktfmt.gradle") version "0.20.1" } } diff --git a/lib/kotlin/src/test/kotlin/org/apache/thrift/MetaDataTest.kt b/lib/kotlin/src/test/kotlin/org/apache/thrift/MetaDataTest.kt index e066bbe4dce..7780aa410b0 100644 --- a/lib/kotlin/src/test/kotlin/org/apache/thrift/MetaDataTest.kt +++ b/lib/kotlin/src/test/kotlin/org/apache/thrift/MetaDataTest.kt @@ -31,12 +31,6 @@ internal class MetaDataTest { assertEquals(3, personMetadata.size) val idField = personMetadata[Person._Fields.ID]!! assertEquals("id", idField.fieldName) - assertEquals( - mapOf( - "max" to "100000", - "min" to "1", - ), - idField.fieldAnnotations - ) + assertEquals(mapOf("max" to "100000", "min" to "1"), idField.fieldAnnotations) } } diff --git a/lib/lua/Makefile.am b/lib/lua/Makefile.am index 3b272f56cbe..ae67d942e85 100644 --- a/lib/lua/Makefile.am +++ b/lib/lua/Makefile.am @@ -57,6 +57,9 @@ liblualongnumber_la_CPPFLAGS = $(AM_CPPFLAGS) $(LUA_INCLUDE) -DLUA_COMPAT_MODULE liblualongnumber_la_LDFLAGS = $(AM_LDFLAGS) liblualongnumber_la_LIBADD = $(LUA_LIB) -lm +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ coding_standards.md \ TBinaryProtocol.lua \ diff --git a/lib/lua/TBinaryProtocol.lua b/lib/lua/TBinaryProtocol.lua index 4b8e98a9d1f..9eacc4ae8ab 100644 --- a/lib/lua/TBinaryProtocol.lua +++ b/lib/lua/TBinaryProtocol.lua @@ -18,8 +18,8 @@ -- require 'TProtocol' -require 'libluabpack' -require 'libluabitwise' +local libluabpack = require 'libluabpack' +local libluabitwise = require 'libluabitwise' TBinaryProtocol = __TObject.new(TProtocolBase, { __type = 'TBinaryProtocol', @@ -111,6 +111,11 @@ function TBinaryProtocol:writeI32(i32) self.trans:write(buff) end +function TBinaryProtocol:writeUI32(i32) + local buff = libluabpack.bpack('I', i32) + self.trans:write(buff) +end + function TBinaryProtocol:writeI64(i64) local buff = libluabpack.bpack('l', i64) self.trans:write(buff) @@ -127,6 +132,13 @@ function TBinaryProtocol:writeString(str) self.trans:write(str) end +function TBinaryProtocol:writeUuid(uuid) + self:writeUI32(uuid.two) + self:writeUI32(uuid.three) + self:writeUI32(uuid.zero) + self:writeUI32(uuid.one) +end + function TBinaryProtocol:readMessageBegin() local sz, ttype, name, seqid = self:readI32() if sz < 0 then @@ -226,6 +238,12 @@ function TBinaryProtocol:readI32() return val end +function TBinaryProtocol:readUI32() + local buff = self.trans:readAll(4) + local val = libluabpack.bunpack('I', buff) + return val +end + function TBinaryProtocol:readI64() local buff = self.trans:readAll(8) local val = libluabpack.bunpack('l', buff) @@ -244,6 +262,19 @@ function TBinaryProtocol:readString() return str end +function TBinaryProtocol:readUuid() + local a = self:readUI32() + local b = self:readUI32() + local c = self:readUI32() + local d = self:readUI32() + return TUUID:new { + zero = c, + one = d, + two = a, + three = b + } +end + TBinaryProtocolFactory = TProtocolFactory:new{ __type = 'TBinaryProtocolFactory', strictRead = false diff --git a/lib/lua/TCompactProtocol.lua b/lib/lua/TCompactProtocol.lua index 8ec7b3a2c0c..f01c56f65dd 100644 --- a/lib/lua/TCompactProtocol.lua +++ b/lib/lua/TCompactProtocol.lua @@ -18,9 +18,9 @@ -- require 'TProtocol' -require 'libluabpack' -require 'libluabitwise' -require 'liblualongnumber' +local libluabpack = require 'libluabpack' +local libluabitwise = require 'libluabitwise' +local liblualongnumber = require 'liblualongnumber' TCompactProtocol = __TObject.new(TProtocolBase, { __type = 'TCompactProtocol', @@ -61,7 +61,8 @@ TCompactType = { COMPACT_LIST = 0x09, COMPACT_SET = 0x0A, COMPACT_MAP = 0x0B, - COMPACT_STRUCT = 0x0C + COMPACT_STRUCT = 0x0C, + COMPACT_UUID = 0x0D, } TTypeToCompactType = {} @@ -77,21 +78,23 @@ TTypeToCompactType[TType.LIST] = TCompactType.COMPACT_LIST TTypeToCompactType[TType.SET] = TCompactType.COMPACT_SET TTypeToCompactType[TType.MAP] = TCompactType.COMPACT_MAP TTypeToCompactType[TType.STRUCT] = TCompactType.COMPACT_STRUCT +TTypeToCompactType[TType.UUID] = TCompactType.COMPACT_UUID CompactTypeToTType = {} -CompactTypeToTType[TType.STOP] = TType.STOP -CompactTypeToTType[TCompactType.COMPACT_BOOLEAN_TRUE] = TType.BOOL +CompactTypeToTType[TType.STOP] = TType.STOP +CompactTypeToTType[TCompactType.COMPACT_BOOLEAN_TRUE] = TType.BOOL CompactTypeToTType[TCompactType.COMPACT_BOOLEAN_FALSE] = TType.BOOL -CompactTypeToTType[TCompactType.COMPACT_BYTE] = TType.BYTE -CompactTypeToTType[TCompactType.COMPACT_I16] = TType.I16 -CompactTypeToTType[TCompactType.COMPACT_I32] = TType.I32 -CompactTypeToTType[TCompactType.COMPACT_I64] = TType.I64 -CompactTypeToTType[TCompactType.COMPACT_DOUBLE] = TType.DOUBLE -CompactTypeToTType[TCompactType.COMPACT_BINARY] = TType.STRING -CompactTypeToTType[TCompactType.COMPACT_LIST] = TType.LIST -CompactTypeToTType[TCompactType.COMPACT_SET] = TType.SET -CompactTypeToTType[TCompactType.COMPACT_MAP] = TType.MAP -CompactTypeToTType[TCompactType.COMPACT_STRUCT] = TType.STRUCT +CompactTypeToTType[TCompactType.COMPACT_BYTE] = TType.BYTE +CompactTypeToTType[TCompactType.COMPACT_I16] = TType.I16 +CompactTypeToTType[TCompactType.COMPACT_I32] = TType.I32 +CompactTypeToTType[TCompactType.COMPACT_I64] = TType.I64 +CompactTypeToTType[TCompactType.COMPACT_DOUBLE] = TType.DOUBLE +CompactTypeToTType[TCompactType.COMPACT_BINARY] = TType.STRING +CompactTypeToTType[TCompactType.COMPACT_LIST] = TType.LIST +CompactTypeToTType[TCompactType.COMPACT_SET] = TType.SET +CompactTypeToTType[TCompactType.COMPACT_MAP] = TType.MAP +CompactTypeToTType[TCompactType.COMPACT_STRUCT] = TType.STRUCT +CompactTypeToTType[TCompactType.COMPACT_UUID] = TType.UUID function TCompactProtocol:resetLastField() self.lastField = {} @@ -197,6 +200,11 @@ function TCompactProtocol:writeI32(i32) self:writeVarint32(libluabpack.i32ToZigzag(i32)) end +function TCompactProtocol:writeUI32(i32) + local buff = libluabpack.bpack('I', i32) + self.trans:write(buff) +end + function TCompactProtocol:writeI64(i64) self:writeVarint64(libluabpack.i64ToZigzag(i64)) end @@ -211,6 +219,13 @@ function TCompactProtocol:writeString(str) self:writeBinary(str) end +function TCompactProtocol:writeUuid(uuid) + self:writeUI32(uuid.two) + self:writeUI32(uuid.three) + self:writeUI32(uuid.zero) + self:writeUI32(uuid.one) +end + function TCompactProtocol:writeBinary(str) -- Should be utf-8 self:writeVarint32(string.len(str)) @@ -385,6 +400,12 @@ function TCompactProtocol:readI32() return value end +function TCompactProtocol:readUI32() + local buff = self.trans:readAll(4) + local val = libluabpack.bunpack('I', buff) + return val +end + function TCompactProtocol:readI64() local value = self:readVarint64() return value @@ -400,6 +421,19 @@ function TCompactProtocol:readString() return self:readBinary() end +function TCompactProtocol:readUuid() + local a = self:readUI32() + local b = self:readUI32() + local c = self:readUI32() + local d = self:readUI32() + return TUUID:new { + zero = c, + one = d, + two = a, + three = b + } +end + function TCompactProtocol:readBinary() local size = self:readVarint32() if size <= 0 then diff --git a/lib/lua/TFramedTransport.lua b/lib/lua/TFramedTransport.lua index 768e2d99742..4f41e834128 100644 --- a/lib/lua/TFramedTransport.lua +++ b/lib/lua/TFramedTransport.lua @@ -18,7 +18,7 @@ -- require 'TTransport' -require 'libluabpack' +local libluabpack = require 'libluabpack' TFramedTransport = TTransportBase:new{ __type = 'TFramedTransport', diff --git a/lib/lua/THttpTransport.lua b/lib/lua/THttpTransport.lua index 2951db79ff8..e1318c3ffea 100644 --- a/lib/lua/THttpTransport.lua +++ b/lib/lua/THttpTransport.lua @@ -160,12 +160,21 @@ function THttpTransport:writeHttpHeader(content_len) end end +function THttpTransport:flushOneway() + self.wBuf = '' + self:writeHttpHeader(0) + self.trans:flush() +end + function THttpTransport:flush() -- If the write fails we still want wBuf to be clear local tmp = self.wBuf self.wBuf = '' - self:writeHttpHeader(string.len(tmp)) - self.trans:write(tmp) + local dataLen = string.len(tmp) + self:writeHttpHeader(dataLen) + if dataLen > 0 then + self.trans:write(tmp) + end self.trans:flush() end diff --git a/lib/lua/TJsonProtocol.lua b/lib/lua/TJsonProtocol.lua index db08eecf156..cec8e2640aa 100644 --- a/lib/lua/TJsonProtocol.lua +++ b/lib/lua/TJsonProtocol.lua @@ -18,8 +18,9 @@ -- require 'TProtocol' -require 'libluabpack' -require 'libluabitwise' +local libluabpack = require 'libluabpack' +local libluabitwise = require 'libluabitwise' +local liblualongnumber = require 'liblualongnumber' TJSONProtocol = __TObject.new(TProtocolBase, { __type = 'TJSONProtocol', @@ -42,6 +43,7 @@ TTypeToString[TType.STRUCT] = "rec" TTypeToString[TType.LIST] = "lst" TTypeToString[TType.SET] = "set" TTypeToString[TType.MAP] = "map" +TTypeToString[TType.UUID] = "uid" StringToTType = { tf = TType.BOOL, @@ -54,7 +56,8 @@ StringToTType = { rec = TType.STRUCT, map = TType.MAP, set = TType.SET, - lst = TType.LIST + lst = TType.LIST, + uid = TType.UUID, } JSONNode = { @@ -402,13 +405,17 @@ function TJSONProtocol:writeI64(i64) end function TJSONProtocol:writeDouble(dub) - self:writeJSONDouble(string.format("%.16f", dub)) + self:writeJSONDouble(string.format("%.20f", dub)) end function TJSONProtocol:writeString(str) self:writeJSONString(str) end +function TJSONProtocol:writeUuid(uuid) + self:writeJSONString(uuid:getString()) +end + function TJSONProtocol:writeBinary(str) -- Should be utf-8 self:writeJSONBase64(str) @@ -706,6 +713,10 @@ function TJSONProtocol:readString() return self:readJSONString() end +function TJSONProtocol:readUuid() + return TUUIDfromString(self:readJSONString()) +end + function TJSONProtocol:readBinary() return self:readJSONBase64() end diff --git a/lib/lua/TProtocol.lua b/lib/lua/TProtocol.lua index 1306fb3d8c3..f7a993f0b50 100644 --- a/lib/lua/TProtocol.lua +++ b/lib/lua/TProtocol.lua @@ -86,6 +86,7 @@ function TProtocolBase:writeI32(i32) end function TProtocolBase:writeI64(i64) end function TProtocolBase:writeDouble(dub) end function TProtocolBase:writeString(str) end +function TProtocolBase:writeUuid(uuid) end function TProtocolBase:readMessageBegin() end function TProtocolBase:readMessageEnd() end function TProtocolBase:readStructBegin() end @@ -105,6 +106,7 @@ function TProtocolBase:readI32() end function TProtocolBase:readI64() end function TProtocolBase:readDouble() end function TProtocolBase:readString() end +function TProtocolBase:readUuid() end function TProtocolBase:skip(ttype) if ttype == TType.BOOL then @@ -151,6 +153,8 @@ function TProtocolBase:skip(ttype) self:skip(ettype) end self:readListEnd() + elseif ttype == TType.UUID then + self:readUuid() else terror(TProtocolException:new{ message = 'Invalid data' diff --git a/lib/lua/TSocket.lua b/lib/lua/TSocket.lua index d71fc1f984e..47ca6f01faf 100644 --- a/lib/lua/TSocket.lua +++ b/lib/lua/TSocket.lua @@ -17,7 +17,7 @@ -- require 'TTransport' -require 'libluasocket' +local luasocket = require 'libluasocket' -- TSocketBase TSocketBase = TTransportBase:new{ diff --git a/lib/lua/TTransport.lua b/lib/lua/TTransport.lua index 01c7e597971..b7f6b830acc 100644 --- a/lib/lua/TTransport.lua +++ b/lib/lua/TTransport.lua @@ -76,6 +76,8 @@ function TTransportBase:readAll(len) return buf end function TTransportBase:write(buf) end +-- flushOneway is a NOOP for most transport types. +function TTransportBase:flushOneway() end function TTransportBase:flush() end TServerTransportBase = __TObject:new{ diff --git a/lib/lua/Thrift.lua b/lib/lua/Thrift.lua index 1f9a562fac0..b6e3628ae47 100644 --- a/lib/lua/Thrift.lua +++ b/lib/lua/Thrift.lua @@ -23,6 +23,9 @@ --setfenv(1, thrift) package.cpath = package.cpath .. ';bin/?.so' -- TODO FIX + +local libluabitwise = require 'libluabitwise' + function ttype(obj) if type(obj) == 'table' and obj.__type and @@ -48,7 +51,7 @@ function ttable_size(t) return count end -version = '0.20.0' +version = '0.22.0' TType = { STOP = 0, @@ -66,8 +69,7 @@ TType = { MAP = 13, SET = 14, LIST = 15, - UTF8 = 16, - UTF16 = 17 + UUID = 16 } TMessageType = { @@ -233,6 +235,35 @@ function TException:write(oprot) oprot:writeStructEnd() end +TUUID = { + zero, + one, + two, + three +} + +TUUID = __TObject:new{ + __type = 'TUUID' +} + +function TUUIDfromString(str) + local iterator = string.gmatch(str, "[A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9]") + return TUUID:new { + zero = libluabitwise.buor(libluabitwise.ushiftl(tonumber(iterator(), 16), 16), tonumber(iterator(), 16)), + one = libluabitwise.buor(libluabitwise.ushiftl(tonumber(iterator(), 16), 16), tonumber(iterator(), 16)), + two = libluabitwise.buor(libluabitwise.ushiftl(tonumber(iterator(), 16), 16), tonumber(iterator(), 16)), + three = libluabitwise.buor(libluabitwise.ushiftl(tonumber(iterator(), 16), 16), tonumber(iterator(), 16)) + } +end + +function TUUID:getString() + return string.format("%08x-%04x-%04x-%04x-%04x%08x", self.zero, libluabitwise.ushiftr(self.one, 16), libluabitwise.buand(self.one, 0xFFFF), libluabitwise.ushiftr(self.two, 16), libluabitwise.buand(self.two, 0xFFFF), self.three) +end + +function TUUID:__tostring() + return "" +end + -- Basic Client (used in generated lua code) __TClient = __TObject:new{ __type = '__TClient', diff --git a/lib/lua/src/luabitwise.c b/lib/lua/src/luabitwise.c index 2e07e1724ce..ea9110a9c27 100644 --- a/lib/lua/src/luabitwise.c +++ b/lib/lua/src/luabitwise.c @@ -27,6 +27,13 @@ static int l_not(lua_State *L) { return 1; } +static int l_unot(lua_State *L) { + unsigned int a = luaL_checkinteger(L, 1); + a = ~a; + lua_pushnumber(L, a); + return 1; +} + static int l_xor(lua_State *L) { int a = luaL_checkinteger(L, 1); int b = luaL_checkinteger(L, 2); @@ -35,6 +42,15 @@ static int l_xor(lua_State *L) { return 1; } +static int l_uxor(lua_State *L) { + unsigned int a = luaL_checkinteger(L, 1); + unsigned int b = luaL_checkinteger(L, 2); + a ^= b; + lua_pushnumber(L, a); + return 1; +} + + static int l_and(lua_State *L) { int a = luaL_checkinteger(L, 1); int b = luaL_checkinteger(L, 2); @@ -43,6 +59,14 @@ static int l_and(lua_State *L) { return 1; } +static int l_uand(lua_State *L) { + unsigned int a = luaL_checkinteger(L, 1); + unsigned int b = luaL_checkinteger(L, 2); + a &= b; + lua_pushnumber(L, a); + return 1; +} + static int l_or(lua_State *L) { int a = luaL_checkinteger(L, 1); int b = luaL_checkinteger(L, 2); @@ -51,6 +75,14 @@ static int l_or(lua_State *L) { return 1; } +static int l_uor(lua_State *L) { + unsigned int a = luaL_checkinteger(L, 1); + unsigned int b = luaL_checkinteger(L, 2); + a |= b; + lua_pushnumber(L, a); + return 1; +} + static int l_shiftr(lua_State *L) { int a = luaL_checkinteger(L, 1); int b = luaL_checkinteger(L, 2); @@ -59,6 +91,14 @@ static int l_shiftr(lua_State *L) { return 1; } +static int l_ushiftr(lua_State *L) { + unsigned int a = luaL_checkinteger(L, 1); + unsigned int b = luaL_checkinteger(L, 2); + a = a >> b; + lua_pushnumber(L, a); + return 1; +} + static int l_shiftl(lua_State *L) { int a = luaL_checkinteger(L, 1); int b = luaL_checkinteger(L, 2); @@ -67,17 +107,36 @@ static int l_shiftl(lua_State *L) { return 1; } +static int l_ushiftl(lua_State *L) { + unsigned int a = luaL_checkinteger(L, 1); + unsigned int b = luaL_checkinteger(L, 2); + a = a << b; + lua_pushnumber(L, a); + return 1; +} + static const struct luaL_Reg funcs[] = { {"band", l_and}, + {"buand", l_uand}, {"bor", l_or}, + {"buor", l_uor}, {"bxor", l_xor}, + {"buxor", l_uxor}, {"bnot", l_not}, + {"bunot", l_unot}, {"shiftl", l_shiftl}, + {"ushiftl", l_ushiftl}, {"shiftr", l_shiftr}, + {"ushiftr", l_ushiftr}, {NULL, NULL} }; int luaopen_libluabitwise(lua_State *L) { +#if LUA_VERSION_NUM >= 502 + lua_newtable(L); + luaL_setfuncs(L, funcs, 0); +#else luaL_register(L, "libluabitwise", funcs); +#endif return 1; } diff --git a/lib/lua/src/luabpack.c b/lib/lua/src/luabpack.c index 077b6aa0764..cdfb72a9d99 100644 --- a/lib/lua/src/luabpack.c +++ b/lib/lua/src/luabpack.c @@ -45,6 +45,7 @@ static int64_t T_ntohll(uint64_t data) { * c - Signed Byte * s - Signed Short * i - Signed Int + * I - Unsigned Int * l - Signed Long * d - Double */ @@ -72,6 +73,12 @@ static int l_bpack(lua_State *L) { luaL_addlstring(&buf, (void*)&data, sizeof(data)); break; } + case 'I': { + uint32_t data = luaL_checkinteger(L, 2); + data = (uint32_t)htonl(data); + luaL_addlstring(&buf, (void*)&data, sizeof(data)); + break; + } case 'l': { int64_t data = lualongnumber_checklong(L, 2); data = (int64_t)T_htonll(data); @@ -97,6 +104,7 @@ static int l_bpack(lua_State *L) { * C - Unsigned Byte * s - Signed Short * i - Signed Int + * I - Unsigned Int * l - Signed Long * d - Double */ @@ -144,6 +152,17 @@ static int l_bunpack(lua_State *L) { lua_pushnumber(L, val); break; } + /** + * unpack unsigned Int. + */ + case 'I': { + uint32_t val; + luaL_argcheck(L, len == sizeof(val), 1, "Invalid input string size."); + memcpy(&val, data, sizeof(val)); + val = (uint32_t)ntohl(val); + lua_pushnumber(L, val); + break; + } case 'l': { int64_t val; luaL_argcheck(L, len == sizeof(val), 1, "Invalid input string size."); @@ -303,6 +322,11 @@ static const struct luaL_Reg lua_bpack[] = { }; int luaopen_libluabpack(lua_State *L) { +#if LUA_VERSION_NUM >= 502 + lua_newtable(L); + luaL_setfuncs(L, lua_bpack, 0); +#else luaL_register(L, "libluabpack", lua_bpack); +#endif return 1; } diff --git a/lib/lua/src/lualongnumber.c b/lib/lua/src/lualongnumber.c index 9001e4a90dd..91df70a236c 100644 --- a/lib/lua/src/lualongnumber.c +++ b/lib/lua/src/lualongnumber.c @@ -223,6 +223,11 @@ LUALIB_API int luaopen_liblualongnumber(lua_State *L) { lua_pop(L, 1); set_methods(L, LONG_NUM_TYPE, methods); +#if LUA_VERSION_NUM >= 502 + lua_newtable(L); + luaL_setfuncs(L, funcs, 0); +#else luaL_register(L, "liblualongnumber", funcs); +#endif return 1; } diff --git a/lib/lua/src/luasocket.c b/lib/lua/src/luasocket.c index 6f63d3dbfa1..07524ab6a02 100644 --- a/lib/lua/src/luasocket.c +++ b/lib/lua/src/luasocket.c @@ -185,8 +185,12 @@ int luaopen_libluasocket(lua_State *L) { set_methods(L, SOCKET_GENERIC, methods_generic); set_methods(L, SOCKET_CLIENT, methods_client); set_methods(L, SOCKET_SERVER, methods_server); - +#if LUA_VERSION_NUM >= 502 + lua_newtable(L); + luaL_setfuncs(L, funcs_luasocket, 0); +#else luaL_register(L, "luasocket", funcs_luasocket); +#endif return 1; } diff --git a/lib/lua/src/usocket.c b/lib/lua/src/usocket.c index 21c0bac9e92..27103a06b6c 100644 --- a/lib/lua/src/usocket.c +++ b/lib/lua/src/usocket.c @@ -205,21 +205,35 @@ T_ERRCODE socket_connect(p_socket sock, p_sa addr, int addr_len, int timeout) { return socket_wait(sock, WAIT_MODE_C, timeout); } +#define SEND_RETRY_COUNT 5 T_ERRCODE socket_send( p_socket sock, const char *data, size_t len, int timeout) { int err, put = 0; if (*sock < 0) { return CLOSED; } - do { - put = send(*sock, data, len, 0); - if (put > 0) { - return SUCCESS; - } - } while ((err = errno) == EINTR); + for(int i = 0; i < SEND_RETRY_COUNT; i++) { + do { + size_t l = len - put; + put = send(*sock, data + put, l, 0); + if (put > 0) { + if(put == l) { + return SUCCESS; + } + // Not all data was delivered, we need to try again. + err = EAGAIN; + break; + } + } while ((err = errno) == EINTR); - if (err == EAGAIN) { - return socket_wait(sock, WAIT_MODE_W, timeout); + if (err == EAGAIN) { + err = socket_wait(sock, WAIT_MODE_W, timeout); + // Check if the socket is available again and try to resend. + if(err == SUCCESS) { + continue; + } + } + break; } return err; diff --git a/lib/netstd/Benchmarks/Thrift.Benchmarks/Thrift.Benchmarks.csproj b/lib/netstd/Benchmarks/Thrift.Benchmarks/Thrift.Benchmarks.csproj index a8543a3bf37..9d25c7271c6 100644 --- a/lib/netstd/Benchmarks/Thrift.Benchmarks/Thrift.Benchmarks.csproj +++ b/lib/netstd/Benchmarks/Thrift.Benchmarks/Thrift.Benchmarks.csproj @@ -20,7 +20,8 @@ Exe - net8.0 + net9.0 + 0.22.0 latestMajor false true @@ -28,7 +29,7 @@ - + diff --git a/lib/netstd/Makefile.am b/lib/netstd/Makefile.am index 47b38030932..ed855e45f3f 100644 --- a/lib/netstd/Makefile.am +++ b/lib/netstd/Makefile.am @@ -17,13 +17,15 @@ # under the License. # -SUBDIRS = . +SUBDIRS = . all-local: $(DOTNETCORE) build -c Release check-local: - $(DOTNETCORE) test Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift.PublicInterfaces.Compile.Tests.csproj + $(DOTNETCORE) test Tests/Thrift.Compile.Tests/Thrift.Compile.net8/Thrift.Compile.net8.csproj + $(DOTNETCORE) test Tests/Thrift.Compile.Tests/Thrift.Compile.net9/Thrift.Compile.net9.csproj + $(DOTNETCORE) test Tests/Thrift.Compile.Tests/Thrift.Compile.netstd2/Thrift.Compile.netstd2.csproj $(DOTNETCORE) test Tests/Thrift.Tests/Thrift.Tests.csproj $(DOTNETCORE) test Tests/Thrift.IntegrationTests/Thrift.IntegrationTests.csproj @@ -36,8 +38,15 @@ clean-local: $(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 + $(RM) -r Tests/Thrift.Compile.Tests/Thrift.Compile.net8/bin + $(RM) -r Tests/Thrift.Compile.Tests/Thrift.Compile.net8/obj + $(RM) -r Tests/Thrift.Compile.Tests/Thrift.Compile.net9/bin + $(RM) -r Tests/Thrift.Compile.Tests/Thrift.Compile.net9/obj + $(RM) -r Tests/Thrift.Compile.Tests/Thrift.Compile.netstd2/bin + $(RM) -r Tests/Thrift.Compile.Tests/Thrift.Compile.netstd2/obj + +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am EXTRA_DIST = \ README.md \ @@ -45,11 +54,12 @@ EXTRA_DIST = \ Benchmarks/Thrift.Benchmarks \ Tests/Thrift.IntegrationTests/Protocols \ Tests/Thrift.IntegrationTests/Thrift.IntegrationTests.csproj \ - Tests/Thrift.PublicInterfaces.Compile.Tests \ - Tests/Thrift.PublicInterfaces.Compile.Tests/CassandraTest.thrift \ - Tests/Thrift.PublicInterfaces.Compile.Tests/optional_required_default.thrift \ - Tests/Thrift.PublicInterfaces.Compile.Tests/Properties/AssemblyInfo.cs \ - Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift.PublicInterfaces.Compile.Tests.csproj \ + Tests/Thrift.Compile.Tests \ + Tests/Thrift.Compile.Tests/CassandraTest.thrift \ + Tests/Thrift.Compile.Tests/optional_required_default.thrift \ + Tests/Thrift.Compile.Tests/Thrift.Compile.net8/Thrift.Compile.net8.csproj \ + Tests/Thrift.Compile.Tests/Thrift.Compile.net9/Thrift.Compile.net9.csproj \ + Tests/Thrift.Compile.Tests/Thrift.Compile.netstd2/Thrift.Compile.netstd2.csproj \ Tests/Thrift.Tests/Collections \ Tests/Thrift.Tests/DataModel \ Tests/Thrift.Tests/Protocols \ @@ -74,4 +84,3 @@ EXTRA_DIST = \ build.sh \ runtests.cmd \ runtests.sh - diff --git a/lib/netstd/README.md b/lib/netstd/README.md index d554e38543b..912ea011c1d 100644 --- a/lib/netstd/README.md +++ b/lib/netstd/README.md @@ -5,13 +5,14 @@ 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 +- Get Thrift IDL compiler executable, add to some folder and add path to this folder into PATH variable. +- Alternatively, build from source by using the cmake target "copy-thrift-compiler", which places the binary to a suitable place. - Open the Thrift.sln project with Visual Studio and build. or - Build with scripts ## How to build on Unix/Linux -- Ensure you have .NET Core SDK 3.1 (LTS) installed, or use the [Ubuntu docker image](../../build/docker/README.md) +- Ensure you have a suitable .NET Core SDK installed, or use the [Ubuntu docker image](../../build/docker/README.md) - Follow common automake build practice: `./ bootstrap && ./ configure && make` ## Known issues diff --git a/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/CassandraTest.thrift b/lib/netstd/Tests/Thrift.Compile.Tests/CassandraTest.thrift similarity index 100% rename from lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/CassandraTest.thrift rename to lib/netstd/Tests/Thrift.Compile.Tests/CassandraTest.thrift diff --git a/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/GlobalSuppressions.cs b/lib/netstd/Tests/Thrift.Compile.Tests/GlobalSuppressions.cs similarity index 100% rename from lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/GlobalSuppressions.cs rename to lib/netstd/Tests/Thrift.Compile.Tests/GlobalSuppressions.cs diff --git a/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Impl/Thrift5253/MyService.cs b/lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.net8/Impl/Thrift5253/MyService.cs similarity index 97% rename from lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Impl/Thrift5253/MyService.cs rename to lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.net8/Impl/Thrift5253/MyService.cs index f42337630e1..f192c7f5298 100644 --- a/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Impl/Thrift5253/MyService.cs +++ b/lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.net8/Impl/Thrift5253/MyService.cs @@ -22,7 +22,7 @@ using System.Threading.Tasks; using Thrift5253; -namespace Thrift.PublicInterfaces.Compile.Tests.Impl.Thrift5253 +namespace Thrift.Compile.net8.Impl.Thrift5253 { class MyServiceImpl : MyService.IAsync { diff --git a/lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.net8/Properties/AssemblyInfo.cs b/lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.net8/Properties/AssemblyInfo.cs new file mode 100644 index 00000000000..5bd3c6fb603 --- /dev/null +++ b/lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.net8/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("1b468b7a-a53b-46de-90da-5f9ad7707ef4")] \ 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.Compile.Tests/Thrift.Compile.net8/Thrift.Compile.net8.csproj similarity index 72% rename from lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift.PublicInterfaces.Compile.Tests.csproj rename to lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.net8/Thrift.Compile.net8.csproj index 7c5775026b8..6398a41e4e0 100644 --- a/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift.PublicInterfaces.Compile.Tests.csproj +++ b/lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.net8/Thrift.Compile.net8.csproj @@ -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 @@ -19,13 +19,13 @@ --> - 0.20.0 + 0.22.0 Thrift version $(ThriftVersion) net8.0 latestMajor $(ThriftVersion).0 - Thrift.PublicInterfaces.Compile.Tests - Thrift.PublicInterfaces.Compile.Tests + Thrift.Compile.net8 + Thrift.Compile.net8 false false false @@ -34,11 +34,11 @@ - + - + @@ -46,19 +46,22 @@ + + + - + - + - + - + @@ -69,14 +72,18 @@ - - - - - - - - + + + + + + + + + + + + diff --git a/lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.net9/Impl/Thrift5253/MyService.cs b/lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.net9/Impl/Thrift5253/MyService.cs new file mode 100644 index 00000000000..86a7617e80e --- /dev/null +++ b/lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.net9/Impl/Thrift5253/MyService.cs @@ -0,0 +1,70 @@ +// 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 Thrift5253; + +namespace Thrift.Compile.net9.Impl.Thrift5253 +{ + class MyServiceImpl : MyService.IAsync + { + public Task AsyncProcessor_(AsyncProcessor? input, CancellationToken cancellationToken = default) + { + return Task.FromResult(new AsyncProcessor() { Foo = input?.Foo ?? 0 }); + } + + public Task Broken(BrokenArgs? input, CancellationToken cancellationToken = default) + { + return Task.FromResult(new BrokenResult() { Foo = input?.Foo ?? 0 }); + } + + public Task Client_(Client? input, CancellationToken cancellationToken = default) + { + _ = cancellationToken; + return Task.FromResult(new Client() { Foo = input?.Foo ?? 0 }); + } + + public Task IAsync_(IAsync? input, CancellationToken cancellationToken = default) + { + return Task.FromResult(new IAsync() { Foo = input?.Foo ?? 0 }); + } + + public Task InternalStructs_(InternalStructs? input, CancellationToken cancellationToken = default) + { + return Task.FromResult(new InternalStructs() { Foo = input?.Foo ?? 0 }); + } + + public Task TestAsync(CancellationToken cancellationToken = default) + { + return Task.CompletedTask; + } + + public Task TestXsync(CancellationToken cancellationToken = default) + { + return Task.CompletedTask; + } + + public Task Works(WorksArrrgs? input, CancellationToken cancellationToken = default) + { + return Task.FromResult(new WorksRslt() { Foo = input?.Foo ?? 0 }); + } + } +} diff --git a/lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.net9/Properties/AssemblyInfo.cs b/lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.net9/Properties/AssemblyInfo.cs new file mode 100644 index 00000000000..5bd3c6fb603 --- /dev/null +++ b/lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.net9/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("1b468b7a-a53b-46de-90da-5f9ad7707ef4")] \ No newline at end of file diff --git a/lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.net9/Thrift.Compile.net9.csproj b/lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.net9/Thrift.Compile.net9.csproj new file mode 100644 index 00000000000..ac1a62a388b --- /dev/null +++ b/lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.net9/Thrift.Compile.net9.csproj @@ -0,0 +1,89 @@ + + + + + 0.22.0 + Thrift version $(ThriftVersion) + net9.0 + latestMajor + $(ThriftVersion).0 + Thrift.Compile.net9 + Thrift.Compile.net9 + false + false + false + false + enable + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.netstd2/Impl/Thrift5253/MyService.cs b/lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.netstd2/Impl/Thrift5253/MyService.cs new file mode 100644 index 00000000000..cbdc497c1e4 --- /dev/null +++ b/lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.netstd2/Impl/Thrift5253/MyService.cs @@ -0,0 +1,70 @@ +// 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 Thrift5253; + +namespace Thrift.Compile.netstd2.Impl.Thrift5253 +{ + class MyServiceImpl : MyService.IAsync + { + public Task AsyncProcessor_(AsyncProcessor input, CancellationToken cancellationToken = default) + { + return Task.FromResult(new AsyncProcessor() { Foo = input?.Foo ?? 0 }); + } + + public Task Broken(BrokenArgs input, CancellationToken cancellationToken = default) + { + return Task.FromResult(new BrokenResult() { Foo = input?.Foo ?? 0 }); + } + + public Task Client_(Client input, CancellationToken cancellationToken = default) + { + _ = cancellationToken; + return Task.FromResult(new Client() { Foo = input?.Foo ?? 0 }); + } + + public Task IAsync_(IAsync input, CancellationToken cancellationToken = default) + { + return Task.FromResult(new IAsync() { Foo = input?.Foo ?? 0 }); + } + + public Task InternalStructs_(InternalStructs input, CancellationToken cancellationToken = default) + { + return Task.FromResult(new InternalStructs() { Foo = input?.Foo ?? 0 }); + } + + public Task TestAsync(CancellationToken cancellationToken = default) + { + return Task.CompletedTask; + } + + public Task TestXsync(CancellationToken cancellationToken = default) + { + return Task.CompletedTask; + } + + public Task Works(WorksArrrgs input, CancellationToken cancellationToken = default) + { + return Task.FromResult(new WorksRslt() { Foo = input?.Foo ?? 0 }); + } + } +} diff --git a/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Properties/AssemblyInfo.cs b/lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.netstd2/Properties/AssemblyInfo.cs similarity index 100% rename from lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Properties/AssemblyInfo.cs rename to lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.netstd2/Properties/AssemblyInfo.cs diff --git a/lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.netstd2/Thrift.Compile.netstd2.csproj b/lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.netstd2/Thrift.Compile.netstd2.csproj new file mode 100644 index 00000000000..1e180617e52 --- /dev/null +++ b/lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.netstd2/Thrift.Compile.netstd2.csproj @@ -0,0 +1,83 @@ + + + + + 0.22.0 + Thrift version $(ThriftVersion) + netstandard2.0 + latestMajor + $(ThriftVersion).0 + Thrift.Compile.netstd2 + Thrift.Compile.netstd2 + false + false + false + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift5253.thrift b/lib/netstd/Tests/Thrift.Compile.Tests/Thrift5253.thrift similarity index 100% rename from lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift5253.thrift rename to lib/netstd/Tests/Thrift.Compile.Tests/Thrift5253.thrift diff --git a/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift5320.enum.thrift b/lib/netstd/Tests/Thrift.Compile.Tests/Thrift5320.enum.thrift similarity index 100% rename from lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift5320.enum.thrift rename to lib/netstd/Tests/Thrift.Compile.Tests/Thrift5320.enum.thrift diff --git a/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift5320.exception.thrift b/lib/netstd/Tests/Thrift.Compile.Tests/Thrift5320.exception.thrift similarity index 89% rename from lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift5320.exception.thrift rename to lib/netstd/Tests/Thrift.Compile.Tests/Thrift5320.exception.thrift index 37421c0acac..d61a3001955 100644 --- a/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift5320.exception.thrift +++ b/lib/netstd/Tests/Thrift.Compile.Tests/Thrift5320.exception.thrift @@ -24,7 +24,10 @@ namespace * Thrift5320.exceptions exception Task { - 1: Task left - 2: Task right + 1: ErrorData data // it would be illegal to use exception as struct type +} + +struct ErrorData { + 1: string messitsch } diff --git a/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift5320.struct.thrift b/lib/netstd/Tests/Thrift.Compile.Tests/Thrift5320.struct.thrift similarity index 100% rename from lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift5320.struct.thrift rename to lib/netstd/Tests/Thrift.Compile.Tests/Thrift5320.struct.thrift diff --git a/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift5320.thrift b/lib/netstd/Tests/Thrift.Compile.Tests/Thrift5320.thrift similarity index 100% rename from lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift5320.thrift rename to lib/netstd/Tests/Thrift.Compile.Tests/Thrift5320.thrift diff --git a/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift5382.objs.thrift b/lib/netstd/Tests/Thrift.Compile.Tests/Thrift5382.objs.thrift similarity index 100% rename from lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift5382.objs.thrift rename to lib/netstd/Tests/Thrift.Compile.Tests/Thrift5382.objs.thrift diff --git a/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift5382.thrift b/lib/netstd/Tests/Thrift.Compile.Tests/Thrift5382.thrift similarity index 100% rename from lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift5382.thrift rename to lib/netstd/Tests/Thrift.Compile.Tests/Thrift5382.thrift diff --git a/lib/netstd/Tests/Thrift.Compile.Tests/Thrift5794.thrift b/lib/netstd/Tests/Thrift.Compile.Tests/Thrift5794.thrift new file mode 100644 index 00000000000..6a73a9be0bf --- /dev/null +++ b/lib/netstd/Tests/Thrift.Compile.Tests/Thrift5794.thrift @@ -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. + */ + +// Testcase for THRIFT-5794 uncompilable code generated w/o net8 option + +namespace * Thrift5794 + +struct foo { + 1: double a; + 2: double b; + 3: double c; +} + +struct bar { + 1: required double a; + 2: required double b; + 3: double c; +} + diff --git a/lib/netstd/Tests/Thrift.Compile.Tests/Thrift5795.thrift b/lib/netstd/Tests/Thrift.Compile.Tests/Thrift5795.thrift new file mode 100644 index 00000000000..7bad8d76a7b --- /dev/null +++ b/lib/netstd/Tests/Thrift.Compile.Tests/Thrift5795.thrift @@ -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. + */ + +// Testcase for THRIFT-5795 namespace not properly escaped + +namespace * Thrift5795.default + + +struct foo { + 1: double bar; +} + diff --git a/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/name_conflicts.enum.thrift b/lib/netstd/Tests/Thrift.Compile.Tests/name_conflicts.enum.thrift similarity index 100% rename from lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/name_conflicts.enum.thrift rename to lib/netstd/Tests/Thrift.Compile.Tests/name_conflicts.enum.thrift diff --git a/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/name_conflicts.thrift b/lib/netstd/Tests/Thrift.Compile.Tests/name_conflicts.thrift similarity index 100% rename from lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/name_conflicts.thrift rename to lib/netstd/Tests/Thrift.Compile.Tests/name_conflicts.thrift diff --git a/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/optional_required_default.thrift b/lib/netstd/Tests/Thrift.Compile.Tests/optional_required_default.thrift similarity index 100% rename from lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/optional_required_default.thrift rename to lib/netstd/Tests/Thrift.Compile.Tests/optional_required_default.thrift diff --git a/lib/netstd/Tests/Thrift.IntegrationTests/Protocols/ProtocolsOperationsTests.cs b/lib/netstd/Tests/Thrift.IntegrationTests/Protocols/ProtocolsOperationsTests.cs index dd9646ad914..f9f3117a6fc 100644 --- a/lib/netstd/Tests/Thrift.IntegrationTests/Protocols/ProtocolsOperationsTests.cs +++ b/lib/netstd/Tests/Thrift.IntegrationTests/Protocols/ProtocolsOperationsTests.cs @@ -23,6 +23,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using Thrift.Protocol; using Thrift.Protocol.Entities; +using Thrift.Transport; using Thrift.Transport.Client; #pragma warning disable IDE0063 // using @@ -55,12 +56,13 @@ public async Task WriteReadMessage_Test(Type protocolType, TMessageType messageT try { var tuple = GetProtocolInstance(protocolType); - using (var stream = tuple.Item1) + using (var stream = tuple.Stream) { - var protocol = tuple.Item2; + var protocol = tuple.Protocol; await protocol.WriteMessageBeginAsync(expected, default); await protocol.WriteMessageEndAsync(default); + await tuple.Transport.FlushAsync(default); stream.Seek(0, SeekOrigin.Begin); @@ -89,12 +91,13 @@ public async Task WriteReadStruct_Test(Type protocolType) try { var tuple = GetProtocolInstance(protocolType); - using (var stream = tuple.Item1) + using (var stream = tuple.Stream) { - var protocol = tuple.Item2; + var protocol = tuple.Protocol; await protocol.WriteStructBeginAsync(expected, default); await protocol.WriteStructEndAsync(default); + await tuple.Transport.FlushAsync(default); stream?.Seek(0, SeekOrigin.Begin); @@ -124,12 +127,13 @@ public async Task WriteReadField_Test(Type protocolType) try { var tuple = GetProtocolInstance(protocolType); - using (var stream = tuple.Item1) + using (var stream = tuple.Stream) { - var protocol = tuple.Item2; + var protocol = tuple.Protocol; await protocol.WriteFieldBeginAsync(expected, default); await protocol.WriteFieldEndAsync(default); + await tuple.Transport.FlushAsync(default); stream?.Seek(0, SeekOrigin.Begin); @@ -157,12 +161,13 @@ public async Task WriteReadMap_Test(Type protocolType) try { var tuple = GetProtocolInstance(protocolType); - using (var stream = tuple.Item1) + using (var stream = tuple.Stream) { - var protocol = tuple.Item2; + var protocol = tuple.Protocol; await protocol.WriteMapBeginAsync(expected, default); await protocol.WriteMapEndAsync(default); + await tuple.Transport.FlushAsync(default); stream?.Seek(0, SeekOrigin.Begin); @@ -191,12 +196,13 @@ public async Task WriteReadList_Test(Type protocolType) try { var tuple = GetProtocolInstance(protocolType); - using (var stream = tuple.Item1) + using (var stream = tuple.Stream) { - var protocol = tuple.Item2; + var protocol = tuple.Protocol; await protocol.WriteListBeginAsync(expected, default); await protocol.WriteListEndAsync(default); + await tuple.Transport.FlushAsync(default); stream?.Seek(0, SeekOrigin.Begin); @@ -224,12 +230,13 @@ public async Task WriteReadSet_Test(Type protocolType) try { var tuple = GetProtocolInstance(protocolType); - using (var stream = tuple.Item1) + using (var stream = tuple.Stream) { - var protocol = tuple.Item2; + var protocol = tuple.Protocol; await protocol.WriteSetBeginAsync(expected, default); await protocol.WriteSetEndAsync(default); + await tuple.Transport.FlushAsync(default); stream?.Seek(0, SeekOrigin.Begin); @@ -257,11 +264,12 @@ public async Task WriteReadBool_Test(Type protocolType) try { var tuple = GetProtocolInstance(protocolType); - using (var stream = tuple.Item1) + using (var stream = tuple.Stream) { - var protocol = tuple.Item2; + var protocol = tuple.Protocol; await protocol.WriteBoolAsync(expected, default); + await tuple.Transport.FlushAsync(default); stream?.Seek(0, SeekOrigin.Begin); @@ -288,11 +296,12 @@ public async Task WriteReadByte_Test(Type protocolType) try { var tuple = GetProtocolInstance(protocolType); - using (var stream = tuple.Item1) + using (var stream = tuple.Stream) { - var protocol = tuple.Item2; + var protocol = tuple.Protocol; await protocol.WriteByteAsync(expected, default); + await tuple.Transport.FlushAsync(default); stream?.Seek(0, SeekOrigin.Begin); @@ -319,11 +328,12 @@ public async Task WriteReadI16_Test(Type protocolType) try { var tuple = GetProtocolInstance(protocolType); - using (var stream = tuple.Item1) + using (var stream = tuple.Stream) { - var protocol = tuple.Item2; + var protocol = tuple.Protocol; await protocol.WriteI16Async(expected, default); + await tuple.Transport.FlushAsync(default); stream?.Seek(0, SeekOrigin.Begin); @@ -350,11 +360,12 @@ public async Task WriteReadI32_Test(Type protocolType) try { var tuple = GetProtocolInstance(protocolType); - using (var stream = tuple.Item1) + using (var stream = tuple.Stream) { - var protocol = tuple.Item2; + var protocol = tuple.Protocol; await protocol.WriteI32Async(expected, default); + await tuple.Transport.FlushAsync(default); stream?.Seek(0, SeekOrigin.Begin); @@ -381,11 +392,12 @@ public async Task WriteReadI64_Test(Type protocolType) try { var tuple = GetProtocolInstance(protocolType); - using (var stream = tuple.Item1) + using (var stream = tuple.Stream) { - var protocol = tuple.Item2; + var protocol = tuple.Protocol; await protocol.WriteI64Async(expected, default); + await tuple.Transport.FlushAsync(default); stream?.Seek(0, SeekOrigin.Begin); @@ -412,11 +424,12 @@ public async Task WriteReadDouble_Test(Type protocolType) try { var tuple = GetProtocolInstance(protocolType); - using (var stream = tuple.Item1) + using (var stream = tuple.Stream) { - var protocol = tuple.Item2; + var protocol = tuple.Protocol; await protocol.WriteDoubleAsync(expected, default); + await tuple.Transport.FlushAsync(default); stream?.Seek(0, SeekOrigin.Begin); @@ -443,11 +456,12 @@ public async Task WriteReadString_Test(Type protocolType) try { var tuple = GetProtocolInstance(protocolType); - using (var stream = tuple.Item1) + using (var stream = tuple.Stream) { - var protocol = tuple.Item2; + var protocol = tuple.Protocol; await protocol.WriteStringAsync(expected, default); + await tuple.Transport.FlushAsync(default); stream?.Seek(0, SeekOrigin.Begin); @@ -474,11 +488,12 @@ public async Task WriteReadBinary_Test(Type protocolType) try { var tuple = GetProtocolInstance(protocolType); - using (var stream = tuple.Item1) + using (var stream = tuple.Stream) { - var protocol = tuple.Item2; + var protocol = tuple.Protocol; await protocol.WriteBinaryAsync(expected, default); + await tuple.Transport.FlushAsync(default); stream?.Seek(0, SeekOrigin.Begin); @@ -494,12 +509,14 @@ public async Task WriteReadBinary_Test(Type protocolType) } } - private static Tuple GetProtocolInstance(Type protocolType) + private record struct ProtocolTransportStack(Stream Stream, TTransport Transport, TProtocol Protocol); + + private static ProtocolTransportStack GetProtocolInstance(Type protocolType) { var memoryStream = new MemoryStream(); var streamClientTransport = new TStreamTransport(memoryStream, memoryStream,Configuration); if( Activator.CreateInstance(protocolType, streamClientTransport) is TProtocol protocol) - return new Tuple(memoryStream, protocol); + return new ProtocolTransportStack(memoryStream, streamClientTransport, protocol); throw new Exception("Unexpected"); } } diff --git a/lib/netstd/Tests/Thrift.IntegrationTests/Thrift.IntegrationTests.csproj b/lib/netstd/Tests/Thrift.IntegrationTests/Thrift.IntegrationTests.csproj index 3f8345926ae..ff8da43e09a 100644 --- a/lib/netstd/Tests/Thrift.IntegrationTests/Thrift.IntegrationTests.csproj +++ b/lib/netstd/Tests/Thrift.IntegrationTests/Thrift.IntegrationTests.csproj @@ -19,11 +19,11 @@ --> - net8.0 + net9.0 latestMajor Thrift.IntegrationTests Thrift.IntegrationTests - 0.20.0.0 + 0.22.0.0 Exe false false @@ -35,11 +35,11 @@ - - - - - + + + + + diff --git a/lib/netstd/Tests/Thrift.Tests/DataModel/ExceptionAsStruct.cs b/lib/netstd/Tests/Thrift.Tests/DataModel/ExceptionAsStruct.cs new file mode 100644 index 00000000000..70486bdf38c --- /dev/null +++ b/lib/netstd/Tests/Thrift.Tests/DataModel/ExceptionAsStruct.cs @@ -0,0 +1,116 @@ +// 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.Text; +using System.Threading.Tasks; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using test.ExceptionStruct; +using Thrift.Collections; +using Thrift.Protocol; +using Thrift.Transport.Client; + +namespace Thrift.Tests.DataModel +{ + // ReSharper disable once InconsistentNaming + [TestClass] + public class ExceptionAsStructTests + { + [TestMethod] + public async Task Test_Serialize_Deserialize() + { + var initial = CreateInitialData(); + var checking = await WriteAndReadBack(initial); + VerifyIdenticalContent(checking, initial); + } + + private static string FormatKey(int i) => $"Test {i}"; + + private static BatchGetResponse CreateInitialData() + { + var initial = new BatchGetResponse() + { + Errors = [], + Responses = [], + }; + + var i = 0; + initial.Errors.Add(FormatKey(++i), new() { Error = ErrorCode.GenericError }); + initial.Errors.Add(FormatKey(++i), new() { Error = ErrorCode.InvalidData }); + initial.Errors.Add(FormatKey(++i), new() { Error = ErrorCode.ServerOverload }); + initial.Responses.Add(FormatKey(++i), new() { Id = FormatKey(i), Data = [0x00, 0x11, 0x22] }); + initial.Responses.Add(FormatKey(++i), new() { Id = FormatKey(i), Data = [0x45, 0x56, 0x64] }); + initial.Responses.Add(FormatKey(++i), new() { Id = FormatKey(i), Data = [0x78, 0x9a, 0xbc] }); + + return initial; + } + + private static async Task WriteAndReadBack(T input) where T : TBase,new() + { + var stream = new MemoryStream(); + var config = new TConfiguration(); + + // write data + var trans = new TStreamTransport(null, stream, config); + var proto = new TCompactProtocol(trans); + await input.WriteAsync(proto, default); + + // read data + stream.Position = 0; + trans = new TStreamTransport(stream, null, config); + proto = new TCompactProtocol(trans); + var output = new T(); + await output.ReadAsync(proto, default); + + return output; + } + + private static void VerifyIdenticalContent(BatchGetResponse left, BatchGetResponse right) + { + // Errors + Assert.IsNotNull(left.Errors); + Assert.IsNotNull(right.Errors); + Assert.AreEqual(left.Errors.Count, right.Errors.Count); + foreach(var key in left.Errors.Keys) + { + Assert.AreEqual(left.Errors[key].Error, right.Errors[key].Error); + } + + // Responses + Assert.IsNotNull(left.Responses); + Assert.IsNotNull(right.Responses); + Assert.AreEqual(left.Responses.Count, right.Responses.Count); + foreach (var key in left.Responses.Keys) + { + Assert.AreEqual(left.Responses[key].Id, right.Responses[key].Id); + + var leftData = left.Responses[key].Data; + var rightData = right.Responses[key].Data; + Assert.IsNotNull(leftData); + Assert.IsNotNull(rightData); + Assert.AreEqual(leftData.Length, rightData.Length); + for (var index = 0; index < leftData.Length; ++index) + Assert.AreEqual(leftData[index], rightData[index]); + } + } + + } +} diff --git a/lib/netstd/Tests/Thrift.Tests/Thrift.Tests.csproj b/lib/netstd/Tests/Thrift.Tests/Thrift.Tests.csproj index a37be1b1046..762fd68c4c1 100644 --- a/lib/netstd/Tests/Thrift.Tests/Thrift.Tests.csproj +++ b/lib/netstd/Tests/Thrift.Tests/Thrift.Tests.csproj @@ -19,23 +19,23 @@ --> - net8.0 + net9.0 latestMajor - 0.20.0.0 + 0.22.0.0 enable - - - - - + + + + + - + diff --git a/lib/netstd/Thrift.sln b/lib/netstd/Thrift.sln index 58c76ced98e..feae3fed931 100644 --- a/lib/netstd/Thrift.sln +++ b/lib/netstd/Thrift.sln @@ -1,6 +1,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.29905.134 +# Visual Studio Version 17 +VisualStudioVersion = 17.9.34728.123 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{ED5A45B0-07D1-4507-96B7-83FBD3D031CA}" EndProject @@ -10,11 +10,15 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Thrift.IntegrationTests", " 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 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Benchmarks", "Benchmarks", "{BF7B896B-8BB6-447C-84F8-26871882A14A}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Thrift.Benchmarks", "Benchmarks\Thrift.Benchmarks\Thrift.Benchmarks.csproj", "{D0559DFF-6632-446C-9EFC-C750DA20B1D9}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Thrift.Benchmarks", "Benchmarks\Thrift.Benchmarks\Thrift.Benchmarks.csproj", "{D0559DFF-6632-446C-9EFC-C750DA20B1D9}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Thrift.Compile.netstd2", "Tests\Thrift.Compile.Tests\Thrift.Compile.netstd2\Thrift.Compile.netstd2.csproj", "{58F72FB9-09F5-4D0F-B0B4-36605670BF72}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Thrift.Compile.net8", "Tests\Thrift.Compile.Tests\Thrift.Compile.net8\Thrift.Compile.net8.csproj", "{9A3E11C0-72FD-4DA0-8E61-C7746E751DF7}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Thrift.Compile.net9", "Tests\Thrift.Compile.Tests\Thrift.Compile.net9\Thrift.Compile.net9.csproj", "{967C48D1-1807-41E5-B4BF-DFA6414CC9F2}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -62,18 +66,6 @@ Global {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 {D0559DFF-6632-446C-9EFC-C750DA20B1D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {D0559DFF-6632-446C-9EFC-C750DA20B1D9}.Debug|Any CPU.Build.0 = Debug|Any CPU {D0559DFF-6632-446C-9EFC-C750DA20B1D9}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -86,6 +78,42 @@ Global {D0559DFF-6632-446C-9EFC-C750DA20B1D9}.Release|x64.Build.0 = Release|Any CPU {D0559DFF-6632-446C-9EFC-C750DA20B1D9}.Release|x86.ActiveCfg = Release|Any CPU {D0559DFF-6632-446C-9EFC-C750DA20B1D9}.Release|x86.Build.0 = Release|Any CPU + {58F72FB9-09F5-4D0F-B0B4-36605670BF72}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {58F72FB9-09F5-4D0F-B0B4-36605670BF72}.Debug|Any CPU.Build.0 = Debug|Any CPU + {58F72FB9-09F5-4D0F-B0B4-36605670BF72}.Debug|x64.ActiveCfg = Debug|Any CPU + {58F72FB9-09F5-4D0F-B0B4-36605670BF72}.Debug|x64.Build.0 = Debug|Any CPU + {58F72FB9-09F5-4D0F-B0B4-36605670BF72}.Debug|x86.ActiveCfg = Debug|Any CPU + {58F72FB9-09F5-4D0F-B0B4-36605670BF72}.Debug|x86.Build.0 = Debug|Any CPU + {58F72FB9-09F5-4D0F-B0B4-36605670BF72}.Release|Any CPU.ActiveCfg = Release|Any CPU + {58F72FB9-09F5-4D0F-B0B4-36605670BF72}.Release|Any CPU.Build.0 = Release|Any CPU + {58F72FB9-09F5-4D0F-B0B4-36605670BF72}.Release|x64.ActiveCfg = Release|Any CPU + {58F72FB9-09F5-4D0F-B0B4-36605670BF72}.Release|x64.Build.0 = Release|Any CPU + {58F72FB9-09F5-4D0F-B0B4-36605670BF72}.Release|x86.ActiveCfg = Release|Any CPU + {58F72FB9-09F5-4D0F-B0B4-36605670BF72}.Release|x86.Build.0 = Release|Any CPU + {9A3E11C0-72FD-4DA0-8E61-C7746E751DF7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9A3E11C0-72FD-4DA0-8E61-C7746E751DF7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9A3E11C0-72FD-4DA0-8E61-C7746E751DF7}.Debug|x64.ActiveCfg = Debug|Any CPU + {9A3E11C0-72FD-4DA0-8E61-C7746E751DF7}.Debug|x64.Build.0 = Debug|Any CPU + {9A3E11C0-72FD-4DA0-8E61-C7746E751DF7}.Debug|x86.ActiveCfg = Debug|Any CPU + {9A3E11C0-72FD-4DA0-8E61-C7746E751DF7}.Debug|x86.Build.0 = Debug|Any CPU + {9A3E11C0-72FD-4DA0-8E61-C7746E751DF7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9A3E11C0-72FD-4DA0-8E61-C7746E751DF7}.Release|Any CPU.Build.0 = Release|Any CPU + {9A3E11C0-72FD-4DA0-8E61-C7746E751DF7}.Release|x64.ActiveCfg = Release|Any CPU + {9A3E11C0-72FD-4DA0-8E61-C7746E751DF7}.Release|x64.Build.0 = Release|Any CPU + {9A3E11C0-72FD-4DA0-8E61-C7746E751DF7}.Release|x86.ActiveCfg = Release|Any CPU + {9A3E11C0-72FD-4DA0-8E61-C7746E751DF7}.Release|x86.Build.0 = Release|Any CPU + {967C48D1-1807-41E5-B4BF-DFA6414CC9F2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {967C48D1-1807-41E5-B4BF-DFA6414CC9F2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {967C48D1-1807-41E5-B4BF-DFA6414CC9F2}.Debug|x64.ActiveCfg = Debug|Any CPU + {967C48D1-1807-41E5-B4BF-DFA6414CC9F2}.Debug|x64.Build.0 = Debug|Any CPU + {967C48D1-1807-41E5-B4BF-DFA6414CC9F2}.Debug|x86.ActiveCfg = Debug|Any CPU + {967C48D1-1807-41E5-B4BF-DFA6414CC9F2}.Debug|x86.Build.0 = Debug|Any CPU + {967C48D1-1807-41E5-B4BF-DFA6414CC9F2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {967C48D1-1807-41E5-B4BF-DFA6414CC9F2}.Release|Any CPU.Build.0 = Release|Any CPU + {967C48D1-1807-41E5-B4BF-DFA6414CC9F2}.Release|x64.ActiveCfg = Release|Any CPU + {967C48D1-1807-41E5-B4BF-DFA6414CC9F2}.Release|x64.Build.0 = Release|Any CPU + {967C48D1-1807-41E5-B4BF-DFA6414CC9F2}.Release|x86.ActiveCfg = Release|Any CPU + {967C48D1-1807-41E5-B4BF-DFA6414CC9F2}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -93,8 +121,10 @@ Global 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} {D0559DFF-6632-446C-9EFC-C750DA20B1D9} = {BF7B896B-8BB6-447C-84F8-26871882A14A} + {58F72FB9-09F5-4D0F-B0B4-36605670BF72} = {ED5A45B0-07D1-4507-96B7-83FBD3D031CA} + {9A3E11C0-72FD-4DA0-8E61-C7746E751DF7} = {ED5A45B0-07D1-4507-96B7-83FBD3D031CA} + {967C48D1-1807-41E5-B4BF-DFA6414CC9F2} = {ED5A45B0-07D1-4507-96B7-83FBD3D031CA} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {FD20BC4A-0109-41D8-8C0C-893E784D7EF9} diff --git a/lib/netstd/Thrift/.editorconfig b/lib/netstd/Thrift/.editorconfig index 82ff4a36058..5f43ecf1b2e 100644 --- a/lib/netstd/Thrift/.editorconfig +++ b/lib/netstd/Thrift/.editorconfig @@ -4,6 +4,6 @@ dotnet_diagnostic.CS1591.severity = silent # silence certain yet unfixed false positives for net8 -dotnet_diagnostic.IDE0290.severity = silent -dotnet_diagnostic.CA1510.severity = silent -dotnet_diagnostic.CA1513.severity = silent +#dotnet_diagnostic.IDE0290.severity = silent +#dotnet_diagnostic.CA1510.severity = silent +#dotnet_diagnostic.CA1513.severity = silent diff --git a/lib/netstd/Thrift/GlobalSuppressions.cs b/lib/netstd/Thrift/GlobalSuppressions.cs index eb7d3d789fa..cb5fc0109d4 100644 --- a/lib/netstd/Thrift/GlobalSuppressions.cs +++ b/lib/netstd/Thrift/GlobalSuppressions.cs @@ -28,4 +28,7 @@ [assembly: SuppressMessage("Style", "IDE0066", Justification = "compatibility", Scope = "module")] [assembly: SuppressMessage("Style", "IDE0090", Justification = "compatibility", Scope = "module")] [assembly: SuppressMessage("Style", "IDE0063", Justification = "compatibility", Scope = "module")] +[assembly: SuppressMessage("Style", "IDE0130", Justification = "compatibility", Scope = "module")] +[assembly: SuppressMessage("Style", "IDE0290", Justification = "compatibility", Scope = "module")] +[assembly: SuppressMessage("Style", "CS0114", Justification = "known issue, see JIRA ticket", Scope = "module")] diff --git a/lib/netstd/Thrift/Properties/AssemblyInfo.cs b/lib/netstd/Thrift/Properties/AssemblyInfo.cs index bd84c4ea37a..84be9807563 100644 --- a/lib/netstd/Thrift/Properties/AssemblyInfo.cs +++ b/lib/netstd/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.20.0.0")] -[assembly: AssemblyFileVersion("0.20.0.0")] +[assembly: AssemblyVersion("0.22.0.0")] +[assembly: AssemblyFileVersion("0.22.0.0")] diff --git a/lib/netstd/Thrift/Protocol/TBinaryProtocol.cs b/lib/netstd/Thrift/Protocol/TBinaryProtocol.cs index 6389184a41c..44fa9f7d995 100644 --- a/lib/netstd/Thrift/Protocol/TBinaryProtocol.cs +++ b/lib/netstd/Thrift/Protocol/TBinaryProtocol.cs @@ -255,7 +255,7 @@ public override async ValueTask ReadMessageBeginAsync(CancellationToke public override Task ReadMessageEndAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); - Transport.ResetConsumedMessageSize(); + Transport.ResetMessageSizeAndConsumedBytes(); return Task.CompletedTask; } @@ -475,7 +475,13 @@ public class Factory : TProtocolFactory protected readonly bool StrictRead; protected readonly bool StrictWrite; - public Factory(bool strictRead = false, bool strictWrite = true) + // emtpy default CTOR required + public Factory() + : this(false, true) + { + } + + public Factory(bool strictRead, bool strictWrite) { StrictRead = strictRead; StrictWrite = strictWrite; diff --git a/lib/netstd/Thrift/Protocol/TCompactProtocol.cs b/lib/netstd/Thrift/Protocol/TCompactProtocol.cs index 8e5d00d14f6..1fd7e50ce54 100644 --- a/lib/netstd/Thrift/Protocol/TCompactProtocol.cs +++ b/lib/netstd/Thrift/Protocol/TCompactProtocol.cs @@ -461,7 +461,7 @@ public override async ValueTask ReadMessageBeginAsync(CancellationToke public override Task ReadMessageEndAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); - Transport.ResetConsumedMessageSize(); + Transport.ResetMessageSizeAndConsumedBytes(); return Task.CompletedTask; } diff --git a/lib/netstd/Thrift/Protocol/TJSONProtocol.cs b/lib/netstd/Thrift/Protocol/TJSONProtocol.cs index 64308d60be6..ae37a807525 100644 --- a/lib/netstd/Thrift/Protocol/TJSONProtocol.cs +++ b/lib/netstd/Thrift/Protocol/TJSONProtocol.cs @@ -29,6 +29,8 @@ #pragma warning disable IDE0079 // net20 - unneeded suppression #pragma warning disable IDE0290 // net8 - primary CTOR +#pragma warning disable IDE0305 // net9 - collection init +#pragma warning disable IDE0300 // net9 - collection init namespace Thrift.Protocol { @@ -698,7 +700,7 @@ public override async Task ReadMessageEndAsync(CancellationToken cancellationTok { cancellationToken.ThrowIfCancellationRequested(); await ReadJsonArrayEndAsync(cancellationToken); - Transport.ResetConsumedMessageSize(); + Transport.ResetMessageSizeAndConsumedBytes(); } public override async ValueTask ReadStructBeginAsync(CancellationToken cancellationToken) diff --git a/lib/netstd/Thrift/Protocol/TProtocolDecorator.cs b/lib/netstd/Thrift/Protocol/TProtocolDecorator.cs index c75cc6319ac..8e7fb94b91f 100644 --- a/lib/netstd/Thrift/Protocol/TProtocolDecorator.cs +++ b/lib/netstd/Thrift/Protocol/TProtocolDecorator.cs @@ -158,7 +158,7 @@ public override async Task ReadMessageEndAsync(CancellationToken cancellationTok { cancellationToken.ThrowIfCancellationRequested(); await _wrappedProtocol.ReadMessageEndAsync(cancellationToken); - Transport.ResetConsumedMessageSize(); + Transport.ResetMessageSizeAndConsumedBytes(); } public override async ValueTask ReadStructBeginAsync(CancellationToken cancellationToken) diff --git a/lib/netstd/Thrift/Thrift.csproj b/lib/netstd/Thrift/Thrift.csproj index d255f37c4eb..760c5d7b94d 100644 --- a/lib/netstd/Thrift/Thrift.csproj +++ b/lib/netstd/Thrift/Thrift.csproj @@ -19,7 +19,7 @@ --> - netstandard2.1;netstandard2.0;net6.0;net7.0;net8.0 + netstandard2.1;netstandard2.0;net8.0;net9.0 Thrift ApacheThrift true @@ -40,8 +40,8 @@ true thrift.snk false - Apache Thrift 0.20.0 - 0.20.0.0 + Apache Thrift 0.22.0 + 0.22.0.0 false http://thrift.apache.org/ Apache Thrift Developers @@ -50,23 +50,28 @@ C# .NET Core bindings for the Apache Thrift RPC system Apache Thrift RPC - https://github.com/apache/thrift/blob/0.20.0/CHANGES.md + https://github.com/apache/thrift/blob/0.22.0/CHANGES.md + https://thrift.apache.org/ + https://github.com/apache/thrift + git README.md - Copyright 2023 The Apache Software Foundation + Copyright 2024 The Apache Software Foundation - - - - + + + - - - - - + + @@ -81,18 +86,18 @@ - - - 7.0.9 - - - - + - 8.0.0 + 8.0.11 + + + 9.0.0 + + + $(IntermediateOutputPath)$(TargetFrameworkMoniker).AssemblyAttributes$(DefaultLanguageSourceExtension) diff --git a/lib/netstd/Thrift/Transport/Client/THttpTransport.cs b/lib/netstd/Thrift/Transport/Client/THttpTransport.cs index 1ab1caf729c..4467681ae1f 100644 --- a/lib/netstd/Thrift/Transport/Client/THttpTransport.cs +++ b/lib/netstd/Thrift/Transport/Client/THttpTransport.cs @@ -25,6 +25,8 @@ using System.Threading; using System.Threading.Tasks; +#pragma warning disable IDE0079 // unneeded suppression -> all except net8 +#pragma warning disable IDE0301 // simplify collection init -> net8 only namespace Thrift.Transport.Client { @@ -165,7 +167,7 @@ public override async ValueTask ReadAsync(byte[] buffer, int offset, int le } catch (IOException iox) { - throw new TTransportException(TTransportException.ExceptionType.Unknown, iox.ToString()); + throw new TTransportException(TTransportException.ExceptionType.Unknown, iox.ToString(), iox); } } @@ -258,21 +260,25 @@ public override async Task FlushAsync(CancellationToken cancellationToken) } catch (IOException iox) { - throw new TTransportException(TTransportException.ExceptionType.Unknown, iox.ToString()); + throw new TTransportException(TTransportException.ExceptionType.Unknown, iox.ToString(), iox); } catch (HttpRequestException wx) { throw new TTransportException(TTransportException.ExceptionType.Unknown, - "Couldn't connect to server: " + wx); + "Couldn't connect to server: " + wx, wx); + } + catch (OperationCanceledException ocx) + { + throw new TTransportException(TTransportException.ExceptionType.Interrupted, ocx.Message, ocx); } catch (Exception ex) { - throw new TTransportException(TTransportException.ExceptionType.Unknown, ex.Message); + throw new TTransportException(TTransportException.ExceptionType.Unknown, ex.Message, ex); } finally { _outputStream = new MemoryStream(); - ResetConsumedMessageSize(); + ResetMessageSizeAndConsumedBytes(); } } diff --git a/lib/netstd/Thrift/Transport/Client/TMemoryBufferTransport.cs b/lib/netstd/Thrift/Transport/Client/TMemoryBufferTransport.cs index 5773d30cb57..47013782c1f 100644 --- a/lib/netstd/Thrift/Transport/Client/TMemoryBufferTransport.cs +++ b/lib/netstd/Thrift/Transport/Client/TMemoryBufferTransport.cs @@ -115,7 +115,7 @@ public void Seek(int delta, SeekOrigin origin) throw new ArgumentException("Cannot seek outside of the valid range",nameof(origin)); Position = newPos; - ResetConsumedMessageSize(); + ResetMessageSizeAndConsumedBytes(); CountConsumedMessageBytes(Position); } @@ -145,7 +145,7 @@ public override Task WriteAsync(byte[] buffer, int offset, int count, Cancellati public override Task FlushAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); - ResetConsumedMessageSize(); + ResetMessageSizeAndConsumedBytes(); return Task.CompletedTask; } diff --git a/lib/netstd/Thrift/Transport/Client/TNamedPipeTransport.cs b/lib/netstd/Thrift/Transport/Client/TNamedPipeTransport.cs index 8e60f9f5e60..3ed1b6cda88 100644 --- a/lib/netstd/Thrift/Transport/Client/TNamedPipeTransport.cs +++ b/lib/netstd/Thrift/Transport/Client/TNamedPipeTransport.cs @@ -54,7 +54,7 @@ public override async Task OpenAsync(CancellationToken cancellationToken) } await PipeStream.ConnectAsync( ConnectTimeout, cancellationToken); - ResetConsumedMessageSize(); + ResetMessageSizeAndConsumedBytes(); } public override void Close() @@ -112,7 +112,7 @@ public override async Task WriteAsync(byte[] buffer, int offset, int length, Can public override async Task FlushAsync(CancellationToken cancellationToken) { await PipeStream.FlushAsync(cancellationToken); - ResetConsumedMessageSize(); + ResetMessageSizeAndConsumedBytes(); } diff --git a/lib/netstd/Thrift/Transport/Client/TStreamTransport.cs b/lib/netstd/Thrift/Transport/Client/TStreamTransport.cs index 7237b8dd27d..a1950014a67 100644 --- a/lib/netstd/Thrift/Transport/Client/TStreamTransport.cs +++ b/lib/netstd/Thrift/Transport/Client/TStreamTransport.cs @@ -16,6 +16,7 @@ // under the License. using System; +using System.Drawing; using System.IO; using System.Threading; using System.Threading.Tasks; @@ -46,10 +47,28 @@ protected Stream InputStream { get => _InputStream; set { _InputStream = value; - ResetConsumedMessageSize(); + ResetMessageSizeAndConsumedBytes(-1); // full reset to configured maximum + UpdateKnownMessageSize(-1); // adjust to real stream size } } + public override void UpdateKnownMessageSize(long size) + { + long adjusted = 0; + + if (InputStream != null) + { + adjusted = MaxMessageSize; + if (size > 0) + adjusted = Math.Min(adjusted, size); + if( InputStream.CanSeek) + adjusted = Math.Min(adjusted, InputStream.Length); + } + + base.UpdateKnownMessageSize(adjusted); + } + + public override bool IsOpen => true; public override Task OpenAsync(CancellationToken cancellationToken) @@ -106,7 +125,7 @@ public override async Task WriteAsync(byte[] buffer, int offset, int length, Can public override async Task FlushAsync(CancellationToken cancellationToken) { await OutputStream.FlushAsync(cancellationToken); - ResetConsumedMessageSize(); + ResetMessageSizeAndConsumedBytes(); } diff --git a/lib/netstd/Thrift/Transport/Client/TTlsSocketTransport.cs b/lib/netstd/Thrift/Transport/Client/TTlsSocketTransport.cs index 0a51c9a2378..df18124dfa4 100644 --- a/lib/netstd/Thrift/Transport/Client/TTlsSocketTransport.cs +++ b/lib/netstd/Thrift/Transport/Client/TTlsSocketTransport.cs @@ -82,6 +82,10 @@ public TTlsSocketTransport(TcpClient client, TConfiguration config, } } + #if NET9_0_OR_GREATER + [Obsolete("SYSLIB0057: X509Certificate2 and X509Certificate constructors for binary and file content are obsolete")] + #pragma warning disable SYSLIB0057 + #endif public TTlsSocketTransport(IPAddress host, int port, TConfiguration config, string certificatePath, RemoteCertificateValidationCallback certValidator = null, @@ -94,6 +98,7 @@ public TTlsSocketTransport(IPAddress host, int port, TConfiguration config, sslProtocols) { } + #pragma warning restore SYSLIB0057 public TTlsSocketTransport(IPAddress host, int port, TConfiguration config, X509Certificate2 certificate = null, diff --git a/lib/netstd/Thrift/Transport/Layered/TBufferedTransport.cs b/lib/netstd/Thrift/Transport/Layered/TBufferedTransport.cs index 7474b7f9359..977dcbfd119 100644 --- a/lib/netstd/Thrift/Transport/Layered/TBufferedTransport.cs +++ b/lib/netstd/Thrift/Transport/Layered/TBufferedTransport.cs @@ -179,10 +179,10 @@ public override void CheckReadBytesAvailable(long numBytes) } } - public override void ResetConsumedMessageSize(long newSize = -1) + public override void ResetMessageSizeAndConsumedBytes(long newSize = -1) { - base.ResetConsumedMessageSize(newSize); - ReadBuffer.ResetConsumedMessageSize(newSize); + base.ResetMessageSizeAndConsumedBytes(newSize); + ReadBuffer.ResetMessageSizeAndConsumedBytes(newSize); } private void CheckNotDisposed() diff --git a/lib/netstd/Thrift/Transport/Layered/TFramedTransport.cs b/lib/netstd/Thrift/Transport/Layered/TFramedTransport.cs index 5e67f10cda6..faa3fa6e90f 100644 --- a/lib/netstd/Thrift/Transport/Layered/TFramedTransport.cs +++ b/lib/netstd/Thrift/Transport/Layered/TFramedTransport.cs @@ -191,10 +191,10 @@ protected override void Dispose(bool disposing) IsDisposed = true; } - public override void ResetConsumedMessageSize(long newSize = -1) + public override void ResetMessageSizeAndConsumedBytes(long newSize = -1) { - base.ResetConsumedMessageSize(newSize); - ReadBuffer.ResetConsumedMessageSize(newSize); + base.ResetMessageSizeAndConsumedBytes(newSize); + ReadBuffer.ResetMessageSizeAndConsumedBytes(newSize); } } } diff --git a/lib/netstd/Thrift/Transport/Layered/TLayeredTransport.cs b/lib/netstd/Thrift/Transport/Layered/TLayeredTransport.cs index 3d855a4f5f0..f9a4ce477af 100644 --- a/lib/netstd/Thrift/Transport/Layered/TLayeredTransport.cs +++ b/lib/netstd/Thrift/Transport/Layered/TLayeredTransport.cs @@ -43,9 +43,9 @@ public override void CheckReadBytesAvailable(long numBytes) InnerTransport.CheckReadBytesAvailable(numBytes); } - public override void ResetConsumedMessageSize(long newSize = -1) + public override void ResetMessageSizeAndConsumedBytes(long newSize = -1) { - InnerTransport.ResetConsumedMessageSize(newSize); + InnerTransport.ResetMessageSizeAndConsumedBytes(newSize); } } } diff --git a/lib/netstd/Thrift/Transport/Server/TNamedPipeServerTransport.cs b/lib/netstd/Thrift/Transport/Server/TNamedPipeServerTransport.cs index 138c7fd9b14..1b6a21f53e9 100644 --- a/lib/netstd/Thrift/Transport/Server/TNamedPipeServerTransport.cs +++ b/lib/netstd/Thrift/Transport/Server/TNamedPipeServerTransport.cs @@ -347,7 +347,7 @@ protected override async ValueTask AcceptImplementationAsync(Cancell catch (Exception e) { Close(); - throw new TTransportException(TTransportException.ExceptionType.NotOpen, e.Message); + throw new TTransportException(TTransportException.ExceptionType.NotOpen, e.Message, e); } } @@ -424,7 +424,7 @@ public override async Task WriteAsync(byte[] buffer, int offset, int length, Can public override async Task FlushAsync(CancellationToken cancellationToken) { await PipeStream.FlushAsync(cancellationToken); - ResetConsumedMessageSize(); + ResetMessageSizeAndConsumedBytes(); } protected override void Dispose(bool disposing) diff --git a/lib/netstd/Thrift/Transport/Server/TServerSocketTransport.cs b/lib/netstd/Thrift/Transport/Server/TServerSocketTransport.cs index 43663c3a78e..96753e1d81f 100644 --- a/lib/netstd/Thrift/Transport/Server/TServerSocketTransport.cs +++ b/lib/netstd/Thrift/Transport/Server/TServerSocketTransport.cs @@ -51,10 +51,10 @@ public TServerSocketTransport(int port, TConfiguration config, int clientTimeout _server.Server.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.IPv6Only, false); _server.Server.NoDelay = true; } - catch (Exception) + catch (Exception ex) { _server = null; - throw new TTransportException("Could not create ServerSocket on port " + port + "."); + throw new TTransportException("Could not create ServerSocket on port " + port + ".", ex); } } @@ -95,7 +95,7 @@ public override void Listen() } catch (SocketException sx) { - throw new TTransportException("Could not accept on listening socket: " + sx.Message); + throw new TTransportException("Could not accept on listening socket: " + sx.Message, sx); } } } @@ -147,7 +147,7 @@ protected override async ValueTask AcceptImplementationAsync(Cancell } catch (Exception ex) { - throw new TTransportException(ex.ToString()); + throw new TTransportException(ex.ToString(), ex); } } @@ -161,7 +161,7 @@ public override void Close() } catch (Exception ex) { - throw new TTransportException("WARNING: Could not close server socket: " + ex); + throw new TTransportException("WARNING: Could not close server socket: " + ex, ex); } _server = null; } diff --git a/lib/netstd/Thrift/Transport/Server/TTlsServerSocketTransport.cs b/lib/netstd/Thrift/Transport/Server/TTlsServerSocketTransport.cs index 0f72438e802..b612d671736 100644 --- a/lib/netstd/Thrift/Transport/Server/TTlsServerSocketTransport.cs +++ b/lib/netstd/Thrift/Transport/Server/TTlsServerSocketTransport.cs @@ -74,10 +74,10 @@ public TTlsServerSocketTransport( _server = new TcpListener(IPAddress.Any, port); _server.Server.NoDelay = true; } - catch (Exception) + catch (Exception ex) { _server = null; - throw new TTransportException($"Could not create ServerSocket on port {port}."); + throw new TTransportException($"Could not create ServerSocket on port {port}.", ex); } } @@ -118,7 +118,7 @@ public override void Listen() } catch (SocketException sx) { - throw new TTransportException($"Could not accept on listening socket: {sx.Message}"); + throw new TTransportException($"Could not accept on listening socket: {sx.Message}", sx); } } } @@ -158,7 +158,7 @@ protected override async ValueTask AcceptImplementationAsync(Cancell } catch (Exception ex) { - throw new TTransportException(ex.ToString()); + throw new TTransportException(ex.ToString(), ex); } } @@ -172,7 +172,7 @@ public override void Close() } catch (Exception ex) { - throw new TTransportException($"WARNING: Could not close server socket: {ex}"); + throw new TTransportException($"WARNING: Could not close server socket: {ex}", ex); } _server = null; diff --git a/lib/netstd/Thrift/Transport/TEndpointTransport.cs b/lib/netstd/Thrift/Transport/TEndpointTransport.cs index 6c781010583..27fb48daf96 100644 --- a/lib/netstd/Thrift/Transport/TEndpointTransport.cs +++ b/lib/netstd/Thrift/Transport/TEndpointTransport.cs @@ -37,13 +37,13 @@ public TEndpointTransport( TConfiguration config) _configuration = config ?? new TConfiguration(); Debug.Assert(Configuration != null); - ResetConsumedMessageSize(); + ResetMessageSizeAndConsumedBytes(); } /// /// Resets RemainingMessageSize to the configured maximum /// - public override void ResetConsumedMessageSize(long newSize = -1) + public override void ResetMessageSizeAndConsumedBytes(long newSize = -1) { // full reset if (newSize < 0) @@ -70,7 +70,7 @@ public override void ResetConsumedMessageSize(long newSize = -1) public override void UpdateKnownMessageSize(long size) { var consumed = KnownMessageSize - RemainingMessageSize; - ResetConsumedMessageSize(size); + ResetMessageSizeAndConsumedBytes(size); CountConsumedMessageBytes(consumed); } @@ -80,7 +80,7 @@ public override void UpdateKnownMessageSize(long size) /// public override void CheckReadBytesAvailable(long numBytes) { - if (RemainingMessageSize < numBytes) + if ((RemainingMessageSize < numBytes) || (numBytes < 0)) throw new TTransportException(TTransportException.ExceptionType.EndOfFile, "MaxMessageSize reached"); } diff --git a/lib/netstd/Thrift/Transport/TTransport.cs b/lib/netstd/Thrift/Transport/TTransport.cs index 44202249243..77ef281674e 100644 --- a/lib/netstd/Thrift/Transport/TTransport.cs +++ b/lib/netstd/Thrift/Transport/TTransport.cs @@ -39,7 +39,7 @@ public abstract class TTransport : IDisposable public abstract TConfiguration Configuration { get; } public abstract void UpdateKnownMessageSize(long size); public abstract void CheckReadBytesAvailable(long numBytes); - public abstract void ResetConsumedMessageSize(long newSize = -1); + public abstract void ResetMessageSizeAndConsumedBytes(long newSize = -1); public void Dispose() { Dispose(true); diff --git a/lib/nodejs/Makefile.am b/lib/nodejs/Makefile.am index 6691579624c..5be81615352 100644 --- a/lib/nodejs/Makefile.am +++ b/lib/nodejs/Makefile.am @@ -20,9 +20,14 @@ stubs: $(top_srcdir)/test/v0.16/ThriftTest.thrift $(THRIFT) --gen js:node -o test/ $(top_srcdir)/test/v0.16/ThriftTest.thrift -deps: $(top_srcdir)/package.json +deps-root: $(top_srcdir)/package.json $(NPM) install $(top_srcdir)/ || $(NPM) install $(top_srcdir)/ +deps-test: test/package.json test/package-lock.json + cd test/ && $(NPM) install && cd .. + +deps: deps-root deps-test + all-local: deps precross: deps stubs @@ -37,6 +42,9 @@ clean-local: $(RM) -r test/episodic-code-generation-test/gen* $(RM) -r test/episodic-code-generation-test/node_modules +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ examples \ lib \ diff --git a/lib/nodejs/examples/client.js b/lib/nodejs/examples/client.js index c83b342349f..29dac26b98f 100644 --- a/lib/nodejs/examples/client.js +++ b/lib/nodejs/examples/client.js @@ -16,28 +16,30 @@ * specific language governing permissions and limitations * under the License. */ -var thrift = require('thrift'); +var thrift = require("thrift"); -var UserStorage = require('./gen-nodejs/UserStorage.js'), - ttypes = require('./gen-nodejs/user_types'); +var UserStorage = require("./gen-nodejs/UserStorage.js"), + ttypes = require("./gen-nodejs/user_types"); -var connection = thrift.createConnection('localhost', 9090), - client = thrift.createClient(UserStorage, connection); +var connection = thrift.createConnection("localhost", 9090), + client = thrift.createClient(UserStorage, connection); -var user = new ttypes.UserProfile({uid: 1, - name: "Mark Slee", - blurb: "I'll find something to put here."}); +var user = new ttypes.UserProfile({ + uid: 1, + name: "Mark Slee", + blurb: "I'll find something to put here.", +}); -connection.on('error', function(err) { +connection.on("error", function (err) { console.error(err); }); -client.store(user, function(err, response) { +client.store(user, function (err, response) { if (err) { console.error(err); } else { console.log("client stored:", user.uid); - client.retrieve(user.uid, function(err, responseUser) { + client.retrieve(user.uid, function (err, responseUser) { if (err) { console.error(err); } else { diff --git a/lib/nodejs/examples/client_multitransport.js b/lib/nodejs/examples/client_multitransport.js index 1e37de32f4f..05e5c315d22 100644 --- a/lib/nodejs/examples/client_multitransport.js +++ b/lib/nodejs/examples/client_multitransport.js @@ -16,43 +16,61 @@ * specific language governing permissions and limitations * under the License. */ -var thrift = require('thrift'), - ttransport = require('thrift/transport'); +var thrift = require("thrift"), + ttransport = require("thrift/transport"); -var UserStorage = require('./gen-nodejs/UserStorage'), - ttypes = require('./gen-nodejs/user_types'); +var UserStorage = require("./gen-nodejs/UserStorage"), + ttypes = require("./gen-nodejs/user_types"); -var f_conn = thrift.createConnection('localhost', 9090), // default: framed - f_client = thrift.createClient(UserStorage, f_conn); -var b_conn = thrift.createConnection('localhost', 9091, {transport: ttransport.TBufferedTransport}), - b_client = thrift.createClient(UserStorage, b_conn); -var user1 = new ttypes.UserProfile({uid: 1, - name: "Mark Slee", - blurb: "I'll find something to put here."}); -var user2 = new ttypes.UserProfile({uid: 2, - name: "Satoshi Tagomori", - blurb: "ok, let's test with buffered transport."}); +var f_conn = thrift.createConnection("localhost", 9090), // default: framed + f_client = thrift.createClient(UserStorage, f_conn); +var b_conn = thrift.createConnection("localhost", 9091, { + transport: ttransport.TBufferedTransport, + }), + b_client = thrift.createClient(UserStorage, b_conn); +var user1 = new ttypes.UserProfile({ + uid: 1, + name: "Mark Slee", + blurb: "I'll find something to put here.", +}); +var user2 = new ttypes.UserProfile({ + uid: 2, + name: "Satoshi Tagomori", + blurb: "ok, let's test with buffered transport.", +}); -f_conn.on('error', function(err) { +f_conn.on("error", function (err) { console.error("framed:", err); }); -f_client.store(user1, function(err, response) { - if (err) { console.error(err); return; } +f_client.store(user1, function (err, response) { + if (err) { + console.error(err); + return; + } console.log("stored:", user1.uid, " as ", user1.name); - b_client.retrieve(user1.uid, function(err, responseUser) { - if (err) { console.error(err); return; } + b_client.retrieve(user1.uid, function (err, responseUser) { + if (err) { + console.error(err); + return; + } console.log("retrieved:", responseUser.uid, " as ", responseUser.name); }); }); -b_client.store(user2, function(err, response) { - if (err) { console.error(err); return; } +b_client.store(user2, function (err, response) { + if (err) { + console.error(err); + return; + } console.log("stored:", user2.uid, " as ", user2.name); - f_client.retrieve(user2.uid, function(err, responseUser) { - if (err) { console.error(err); return; } + f_client.retrieve(user2.uid, function (err, responseUser) { + if (err) { + console.error(err); + return; + } console.log("retrieved:", responseUser.uid, " as ", responseUser.name); }); }); diff --git a/lib/nodejs/examples/hello.js b/lib/nodejs/examples/hello.js index 8b7c4e4ea00..5f1b6822519 100644 --- a/lib/nodejs/examples/hello.js +++ b/lib/nodejs/examples/hello.js @@ -16,46 +16,46 @@ * specific language governing permissions and limitations * under the License. */ -var thrift = require('thrift'); -var HelloSvc = require('./gen-nodejs/HelloSvc.js'); -var TimesTwoSvc = require('./gen-nodejs/TimesTwo.js'); +var thrift = require("thrift"); +var HelloSvc = require("./gen-nodejs/HelloSvc.js"); +var TimesTwoSvc = require("./gen-nodejs/TimesTwo.js"); var helloHandler = { - hello_func: function(result) { - this.call_counter = this.call_counter || 0; - console.log("Client call: " + (++this.call_counter)); - result(null, "Hello Apache Thrift for JavaScript " + this.call_counter); - } -} + hello_func: function (result) { + this.call_counter = this.call_counter || 0; + console.log("Client call: " + ++this.call_counter); + result(null, "Hello Apache Thrift for JavaScript " + this.call_counter); + }, +}; var timesTwoHandler = { - dbl: function(val, result) { - console.log("Client call: " + val); - result(null, val * 2); - } -} + dbl: function (val, result) { + console.log("Client call: " + val); + result(null, val * 2); + }, +}; var helloService = { - transport: thrift.TBufferedTransport, - protocol: thrift.TJSONProtocol, - processor: HelloSvc, - handler: helloHandler + transport: thrift.TBufferedTransport, + protocol: thrift.TJSONProtocol, + processor: HelloSvc, + handler: helloHandler, }; var dblService = { - transport: thrift.TBufferedTransport, - protocol: thrift.TJSONProtocol, - processor: TimesTwoSvc, - handler: timesTwoHandler + transport: thrift.TBufferedTransport, + protocol: thrift.TJSONProtocol, + processor: TimesTwoSvc, + handler: timesTwoHandler, }; var ServerOptions = { - files: ".", - services: { - "/hello": helloService, - "/dbl": dblService, - } -} + files: ".", + services: { + "/hello": helloService, + "/dbl": dblService, + }, +}; var server = thrift.createWebServer(ServerOptions); var port = 8585; diff --git a/lib/nodejs/examples/httpClient.js b/lib/nodejs/examples/httpClient.js index 19cc0c36278..155b5f48915 100644 --- a/lib/nodejs/examples/httpClient.js +++ b/lib/nodejs/examples/httpClient.js @@ -1,23 +1,21 @@ -var thrift = require('thrift'); -var helloSvc = require('./gen-nodejs/HelloSvc.js'); +var thrift = require("thrift"); +var helloSvc = require("./gen-nodejs/HelloSvc.js"); var options = { - transport: thrift.TBufferedTransport, - protocol: thrift.TJSONProtocol, - path: "/hello", - headers: {"Connection": "close"}, - https: false + transport: thrift.TBufferedTransport, + protocol: thrift.TJSONProtocol, + path: "/hello", + headers: { Connection: "close" }, + https: false, }; var connection = thrift.createHttpConnection("localhost", 9090, options); var client = thrift.createHttpClient(helloSvc, connection); -connection.on("error", function(err) { - console.log("Error: " + err); +connection.on("error", function (err) { + console.log("Error: " + err); }); -client.hello_func(function(error, result) { - console.log("Msg from server: " + result); +client.hello_func(function (error, result) { + console.log("Msg from server: " + result); }); - - diff --git a/lib/nodejs/examples/httpServer.js b/lib/nodejs/examples/httpServer.js index acae1369a2f..c4cbc9f8961 100644 --- a/lib/nodejs/examples/httpServer.js +++ b/lib/nodejs/examples/httpServer.js @@ -1,31 +1,30 @@ -var thrift = require('thrift'); -var helloSvc = require('./gen-nodejs/HelloSvc'); +var thrift = require("thrift"); +var helloSvc = require("./gen-nodejs/HelloSvc"); -//ServiceHandler: Implement the hello service +//ServiceHandler: Implement the hello service var helloHandler = { hello_func: function (result) { console.log("Received Hello call"); result(null, "Hello from Node.js"); - } + }, }; //ServiceOptions: The I/O stack for the service -var helloSvcOpt = { - handler: helloHandler, - processor: helloSvc, - protocol: thrift.TJSONProtocol, - transport: thrift.TBufferedTransport -}; +var helloSvcOpt = { + handler: helloHandler, + processor: helloSvc, + protocol: thrift.TJSONProtocol, + transport: thrift.TBufferedTransport, +}; //ServerOptions: Define server features -var serverOpt = { - services: { - "/hello": helloSvcOpt - } -} +var serverOpt = { + services: { + "/hello": helloSvcOpt, + }, +}; -//Create and start the web server -var port = 9090; -thrift.createWebServer(serverOpt).listen(port); +//Create and start the web server +var port = 9090; +thrift.createWebServer(serverOpt).listen(port); console.log("Http/Thrift Server running on port: " + port); - diff --git a/lib/nodejs/examples/httpServer.py b/lib/nodejs/examples/httpServer.py index 76e9f4aa3c8..bf3ef14a247 100644 --- a/lib/nodejs/examples/httpServer.py +++ b/lib/nodejs/examples/httpServer.py @@ -16,5 +16,5 @@ def hello_func(self): protoFactory = TJSONProtocol.TJSONProtocolFactory() port = 9090 server = THttpServer.THttpServer(processor, ("localhost", port), protoFactory) -print "Python server running on port " + str(port) +print("Python server running on port " + str(port)) server.serve() diff --git a/lib/nodejs/examples/parse.js b/lib/nodejs/examples/parse.js index 168a1aeeace..8513e4c2f02 100644 --- a/lib/nodejs/examples/parse.js +++ b/lib/nodejs/examples/parse.js @@ -35,11 +35,11 @@ */ function parseThrift(thriftEncodedData, callback) { - var thrift = require('thrift'); + var thrift = require("thrift"); var transport = new thrift.TFramedTransport(thriftEncodedData); - var protocol = new thrift.TBinaryProtocol(transport); + var protocol = new thrift.TBinaryProtocol(transport); - var clientClass = require('../gen-nodejs/GENERATED').YOUR_CLASS_NAME; + var clientClass = require("../gen-nodejs/GENERATED").YOUR_CLASS_NAME; var client = new clientClass(); client.read(protocol); callback(null, client); diff --git a/lib/nodejs/examples/server.js b/lib/nodejs/examples/server.js index 1c482fe71f7..41492cbe471 100644 --- a/lib/nodejs/examples/server.js +++ b/lib/nodejs/examples/server.js @@ -16,21 +16,21 @@ * specific language governing permissions and limitations * under the License. */ -var thrift = require('thrift'); +var thrift = require("thrift"); -var UserStorage = require('./gen-nodejs/UserStorage.js'), - ttypes = require('./gen-nodejs/user_types'); +var UserStorage = require("./gen-nodejs/UserStorage.js"), + ttypes = require("./gen-nodejs/user_types"); var users = {}; var server = thrift.createServer(UserStorage, { - store: function(user, result) { + store: function (user, result) { console.log("server stored:", user.uid); users[user.uid] = user; result(null); }, - retrieve: function(uid, result) { + retrieve: function (uid, result) { console.log("server retrieved:", uid); result(null, users[uid]); }, diff --git a/lib/nodejs/examples/server_http.js b/lib/nodejs/examples/server_http.js index ef2dc83a295..235f6754885 100644 --- a/lib/nodejs/examples/server_http.js +++ b/lib/nodejs/examples/server_http.js @@ -16,38 +16,46 @@ * specific language governing permissions and limitations * under the License. */ -var connect = require('connect'); -var thrift = require('thrift'); +var connect = require("connect"); +var thrift = require("thrift"); -var UserStorage = require('./gen-nodejs/UserStorage'), - ttypes = require('./gen-nodejs/user_types'); +var UserStorage = require("./gen-nodejs/UserStorage"), + ttypes = require("./gen-nodejs/user_types"); var users = {}; -var store = function(user, result) { +var store = function (user, result) { console.log("stored:", user.uid); users[user.uid] = user; result(null); }; -var retrieve = function(uid, result) { +var retrieve = function (uid, result) { console.log("retrieved:", uid); result(null, users[uid]); }; var server_http = thrift.createHttpServer(UserStorage, { store: store, - retrieve: retrieve + retrieve: retrieve, }); server_http.listen(9090); -var server_connect = connect(thrift.httpMiddleware(UserStorage, { - store: store, - retrieve: retrieve -})); +var server_connect = connect( + thrift.httpMiddleware(UserStorage, { + store: store, + retrieve: retrieve, + }), +); server_http.listen(9091); -var server_connect_json = connect(thrift.httpMiddleware(UserStorage, { - store: store, - retrieve: retrieve -}, {protocol: thrift.TJSONProtocol})); +var server_connect_json = connect( + thrift.httpMiddleware( + UserStorage, + { + store: store, + retrieve: retrieve, + }, + { protocol: thrift.TJSONProtocol }, + ), +); server_connect_json.listen(9092); diff --git a/lib/nodejs/examples/server_multitransport.js b/lib/nodejs/examples/server_multitransport.js index a348e684798..3dc0b17113c 100644 --- a/lib/nodejs/examples/server_multitransport.js +++ b/lib/nodejs/examples/server_multitransport.js @@ -16,31 +16,35 @@ * specific language governing permissions and limitations * under the License. */ -var thrift = require('thrift'), - ttransport = require('thrift/transport'); +var thrift = require("thrift"), + ttransport = require("thrift/transport"); -var UserStorage = require('./gen-nodejs/UserStorage'), - ttypes = require('./gen-nodejs/user_types'); +var UserStorage = require("./gen-nodejs/UserStorage"), + ttypes = require("./gen-nodejs/user_types"); var users = {}; -var store = function(user, result) { +var store = function (user, result) { console.log("stored:", user.uid); users[user.uid] = user; result(null); }; -var retrieve = function(uid, result) { +var retrieve = function (uid, result) { console.log("retrieved:", uid); result(null, users[uid]); }; var server_framed = thrift.createServer(UserStorage, { store: store, - retrieve: retrieve + retrieve: retrieve, }); server_framed.listen(9090); -var server_buffered = thrift.createServer(UserStorage, { - store: store, - retrieve: retrieve -}, {transport: ttransport.TBufferedTransport}); +var server_buffered = thrift.createServer( + UserStorage, + { + store: store, + retrieve: retrieve, + }, + { transport: ttransport.TBufferedTransport }, +); server_buffered.listen(9091); diff --git a/lib/nodejs/lib/thrift/binary.js b/lib/nodejs/lib/thrift/binary.js index 9813ffdb146..e8bbee76f23 100644 --- a/lib/nodejs/lib/thrift/binary.js +++ b/lib/nodejs/lib/thrift/binary.js @@ -26,11 +26,11 @@ var POW_48 = Math.pow(2, 48); var POW_52 = Math.pow(2, 52); var POW_1022 = Math.pow(2, 1022); -exports.readByte = function(b){ - return b > 127 ? b-256 : b; +exports.readByte = function (b) { + return b > 127 ? b - 256 : b; }; -exports.readI16 = function(buff, off) { +exports.readI16 = function (buff, off) { off = off || 0; var v = buff[off + 1]; v += buff[off] << 8; @@ -40,7 +40,7 @@ exports.readI16 = function(buff, off) { return v; }; -exports.readI32 = function(buff, off) { +exports.readI32 = function (buff, off) { off = off || 0; var v = buff[off + 3]; v += buff[off + 2] << 8; @@ -52,14 +52,14 @@ exports.readI32 = function(buff, off) { return v; }; -exports.writeI16 = function(buff, v) { +exports.writeI16 = function (buff, v) { buff[1] = v & 0xff; v >>= 8; buff[0] = v & 0xff; return buff; }; -exports.writeI32 = function(buff, v) { +exports.writeI32 = function (buff, v) { buff[3] = v & 0xff; v >>= 8; buff[2] = v & 0xff; @@ -70,26 +70,26 @@ exports.writeI32 = function(buff, v) { return buff; }; -exports.readDouble = function(buff, off) { +exports.readDouble = function (buff, off) { off = off || 0; var signed = buff[off] & 0x80; - var e = (buff[off+1] & 0xF0) >> 4; - e += (buff[off] & 0x7F) << 4; + var e = (buff[off + 1] & 0xf0) >> 4; + e += (buff[off] & 0x7f) << 4; - var m = buff[off+7]; - m += buff[off+6] << 8; - m += buff[off+5] << 16; - m += buff[off+4] * POW_24; - m += buff[off+3] * POW_32; - m += buff[off+2] * POW_40; - m += (buff[off+1] & 0x0F) * POW_48; + var m = buff[off + 7]; + m += buff[off + 6] << 8; + m += buff[off + 5] << 16; + m += buff[off + 4] * POW_24; + m += buff[off + 3] * POW_32; + m += buff[off + 2] * POW_40; + m += (buff[off + 1] & 0x0f) * POW_48; switch (e) { case 0: e = -1022; break; case 2047: - return m ? NaN : (signed ? -Infinity : Infinity); + return m ? NaN : signed ? -Infinity : Infinity; default: m += POW_52; e -= 1023; @@ -106,10 +106,10 @@ exports.readDouble = function(buff, off) { * Based on code from the jspack module: * http://code.google.com/p/jspack/ */ -exports.writeDouble = function(buff, v) { +exports.writeDouble = function (buff, v) { var m, e, c; - buff[0] = (v < 0 ? 0x80 : 0x00); + buff[0] = v < 0 ? 0x80 : 0x00; v = Math.abs(v); if (v !== v) { @@ -127,22 +127,17 @@ exports.writeDouble = function(buff, v) { c *= 2; } - if (e + 1023 >= 2047) - { + if (e + 1023 >= 2047) { // Overflow m = 0; e = 2047; - } - else if (e + 1023 >= 1) - { + } else if (e + 1023 >= 1) { // Normalized - term order matters, as Math.pow(2, 52-e) and v*Math.pow(2, 52) can overflow - m = (v*c-1) * POW_52; + m = (v * c - 1) * POW_52; e += 1023; - } - else - { + } else { // Denormalized - also catches the '0' case, somewhat by chance - m = (v * POW_1022) * POW_52; + m = v * POW_1022 * POW_52; e = 0; } } diff --git a/lib/nodejs/lib/thrift/binary_protocol.js b/lib/nodejs/lib/thrift/binary_protocol.js index af8836cf52c..fc4df4ae95e 100644 --- a/lib/nodejs/lib/thrift/binary_protocol.js +++ b/lib/nodejs/lib/thrift/binary_protocol.js @@ -17,10 +17,10 @@ * under the License. */ -var log = require('./log'); -var binary = require('./binary'); -var Int64 = require('node-int64'); -var Thrift = require('./thrift'); +var log = require("./log"); +var binary = require("./binary"); +var Int64 = require("node-int64"); +var Thrift = require("./thrift"); var Type = Thrift.Type; module.exports = TBinaryProtocol; @@ -29,96 +29,90 @@ module.exports = TBinaryProtocol; // The largest integer value which can be represented in JavaScript is +/-2^53. // Bitwise operations convert numbers to 32 bit integers but perform sign extension // upon assigning values back to variables. -var VERSION_MASK = -65536, // 0xffff0000 - VERSION_1 = -2147418112, // 0x80010000 - TYPE_MASK = 0x000000ff; +var VERSION_MASK = -65536, // 0xffff0000 + VERSION_1 = -2147418112, // 0x80010000 + TYPE_MASK = 0x000000ff; TBinaryProtocol.VERSION_MASK = VERSION_MASK; TBinaryProtocol.VERSION_1 = VERSION_1; -TBinaryProtocol.TYPE_MASK = TYPE_MASK +TBinaryProtocol.TYPE_MASK = TYPE_MASK; function TBinaryProtocol(trans, strictRead, strictWrite) { this.trans = trans; - this.strictRead = (strictRead !== undefined ? strictRead : false); - this.strictWrite = (strictWrite !== undefined ? strictWrite : true); + this.strictRead = strictRead !== undefined ? strictRead : false; + this.strictWrite = strictWrite !== undefined ? strictWrite : true; this._seqid = null; -}; +} -TBinaryProtocol.prototype.flush = function() { +TBinaryProtocol.prototype.flush = function () { return this.trans.flush(); }; -TBinaryProtocol.prototype.writeMessageBegin = function(name, type, seqid) { - if (this.strictWrite) { - this.writeI32(VERSION_1 | type); - this.writeString(name); - this.writeI32(seqid); - } else { - this.writeString(name); - this.writeByte(type); - this.writeI32(seqid); - } - // Record client seqid to find callback again - if (this._seqid !== null) { - log.warning('SeqId already set', { 'name': name }); - } else { - this._seqid = seqid; - this.trans.setCurrSeqId(seqid); - } +TBinaryProtocol.prototype.writeMessageBegin = function (name, type, seqid) { + if (this.strictWrite) { + this.writeI32(VERSION_1 | type); + this.writeString(name); + this.writeI32(seqid); + } else { + this.writeString(name); + this.writeByte(type); + this.writeI32(seqid); + } + // Record client seqid to find callback again + if (this._seqid !== null) { + log.warning("SeqId already set", { name: name }); + } else { + this._seqid = seqid; + this.trans.setCurrSeqId(seqid); + } }; -TBinaryProtocol.prototype.writeMessageEnd = function() { - if (this._seqid !== null) { - this._seqid = null; - } else { - log.warning('No seqid to unset'); - } +TBinaryProtocol.prototype.writeMessageEnd = function () { + if (this._seqid !== null) { + this._seqid = null; + } else { + log.warning("No seqid to unset"); + } }; -TBinaryProtocol.prototype.writeStructBegin = function(name) { -}; +TBinaryProtocol.prototype.writeStructBegin = function (name) {}; -TBinaryProtocol.prototype.writeStructEnd = function() { -}; +TBinaryProtocol.prototype.writeStructEnd = function () {}; -TBinaryProtocol.prototype.writeFieldBegin = function(name, type, id) { +TBinaryProtocol.prototype.writeFieldBegin = function (name, type, id) { this.writeByte(type); this.writeI16(id); }; -TBinaryProtocol.prototype.writeFieldEnd = function() { -}; +TBinaryProtocol.prototype.writeFieldEnd = function () {}; -TBinaryProtocol.prototype.writeFieldStop = function() { +TBinaryProtocol.prototype.writeFieldStop = function () { this.writeByte(Type.STOP); }; -TBinaryProtocol.prototype.writeMapBegin = function(ktype, vtype, size) { +TBinaryProtocol.prototype.writeMapBegin = function (ktype, vtype, size) { this.writeByte(ktype); this.writeByte(vtype); this.writeI32(size); }; -TBinaryProtocol.prototype.writeMapEnd = function() { -}; +TBinaryProtocol.prototype.writeMapEnd = function () {}; -TBinaryProtocol.prototype.writeListBegin = function(etype, size) { +TBinaryProtocol.prototype.writeListBegin = function (etype, size) { this.writeByte(etype); this.writeI32(size); }; -TBinaryProtocol.prototype.writeListEnd = function() { -}; +TBinaryProtocol.prototype.writeListEnd = function () {}; -TBinaryProtocol.prototype.writeSetBegin = function(etype, size) { +TBinaryProtocol.prototype.writeSetBegin = function (etype, size) { this.writeByte(etype); this.writeI32(size); }; -TBinaryProtocol.prototype.writeSetEnd = function() { -}; +TBinaryProtocol.prototype.writeSetEnd = function () {}; -TBinaryProtocol.prototype.writeBool = function(bool) { +TBinaryProtocol.prototype.writeBool = function (bool) { if (bool) { this.writeByte(1); } else { @@ -126,19 +120,19 @@ TBinaryProtocol.prototype.writeBool = function(bool) { } }; -TBinaryProtocol.prototype.writeByte = function(b) { +TBinaryProtocol.prototype.writeByte = function (b) { this.trans.write(new Buffer([b])); }; -TBinaryProtocol.prototype.writeI16 = function(i16) { +TBinaryProtocol.prototype.writeI16 = function (i16) { this.trans.write(binary.writeI16(new Buffer(2), i16)); }; -TBinaryProtocol.prototype.writeI32 = function(i32) { +TBinaryProtocol.prototype.writeI32 = function (i32) { this.trans.write(binary.writeI32(new Buffer(4), i32)); }; -TBinaryProtocol.prototype.writeI64 = function(i64) { +TBinaryProtocol.prototype.writeI64 = function (i64) { if (i64.buffer) { this.trans.write(i64.buffer); } else { @@ -146,108 +140,110 @@ TBinaryProtocol.prototype.writeI64 = function(i64) { } }; -TBinaryProtocol.prototype.writeDouble = function(dub) { +TBinaryProtocol.prototype.writeDouble = function (dub) { this.trans.write(binary.writeDouble(new Buffer(8), dub)); }; -TBinaryProtocol.prototype.writeStringOrBinary = function(name, encoding, arg) { - if (typeof(arg) === 'string') { +TBinaryProtocol.prototype.writeStringOrBinary = function (name, encoding, arg) { + if (typeof arg === "string") { this.writeI32(Buffer.byteLength(arg, encoding)); this.trans.write(new Buffer(arg, encoding)); - } else if ((arg instanceof Buffer) || - (Object.prototype.toString.call(arg) == '[object Uint8Array]')) { + } else if ( + arg instanceof Buffer || + Object.prototype.toString.call(arg) == "[object Uint8Array]" + ) { // Buffers in Node.js under Browserify may extend UInt8Array instead of // defining a new object. We detect them here so we can write them // correctly this.writeI32(arg.length); this.trans.write(arg); } else { - throw new Error(name + ' called without a string/Buffer argument: ' + arg); + throw new Error(name + " called without a string/Buffer argument: " + arg); } }; -TBinaryProtocol.prototype.writeString = function(arg) { - this.writeStringOrBinary('writeString', 'utf8', arg); +TBinaryProtocol.prototype.writeString = function (arg) { + this.writeStringOrBinary("writeString", "utf8", arg); }; -TBinaryProtocol.prototype.writeBinary = function(arg) { - this.writeStringOrBinary('writeBinary', 'binary', arg); +TBinaryProtocol.prototype.writeBinary = function (arg) { + this.writeStringOrBinary("writeBinary", "binary", arg); }; -TBinaryProtocol.prototype.readMessageBegin = function() { +TBinaryProtocol.prototype.readMessageBegin = function () { var sz = this.readI32(); var type, name, seqid; if (sz < 0) { var version = sz & VERSION_MASK; if (version != VERSION_1) { - throw new Thrift.TProtocolException(Thrift.TProtocolExceptionType.BAD_VERSION, "Bad version in readMessageBegin: " + sz); + throw new Thrift.TProtocolException( + Thrift.TProtocolExceptionType.BAD_VERSION, + "Bad version in readMessageBegin: " + sz, + ); } type = sz & TYPE_MASK; name = this.readString(); seqid = this.readI32(); } else { if (this.strictRead) { - throw new Thrift.TProtocolException(Thrift.TProtocolExceptionType.BAD_VERSION, "No protocol version header"); + throw new Thrift.TProtocolException( + Thrift.TProtocolExceptionType.BAD_VERSION, + "No protocol version header", + ); } name = this.trans.read(sz); type = this.readByte(); seqid = this.readI32(); } - return {fname: name, mtype: type, rseqid: seqid}; + return { fname: name, mtype: type, rseqid: seqid }; }; -TBinaryProtocol.prototype.readMessageEnd = function() { -}; +TBinaryProtocol.prototype.readMessageEnd = function () {}; -TBinaryProtocol.prototype.readStructBegin = function() { - return {fname: ''}; +TBinaryProtocol.prototype.readStructBegin = function () { + return { fname: "" }; }; -TBinaryProtocol.prototype.readStructEnd = function() { -}; +TBinaryProtocol.prototype.readStructEnd = function () {}; -TBinaryProtocol.prototype.readFieldBegin = function() { +TBinaryProtocol.prototype.readFieldBegin = function () { var type = this.readByte(); if (type == Type.STOP) { - return {fname: null, ftype: type, fid: 0}; + return { fname: null, ftype: type, fid: 0 }; } var id = this.readI16(); - return {fname: null, ftype: type, fid: id}; + return { fname: null, ftype: type, fid: id }; }; -TBinaryProtocol.prototype.readFieldEnd = function() { -}; +TBinaryProtocol.prototype.readFieldEnd = function () {}; -TBinaryProtocol.prototype.readMapBegin = function() { +TBinaryProtocol.prototype.readMapBegin = function () { var ktype = this.readByte(); var vtype = this.readByte(); var size = this.readI32(); - return {ktype: ktype, vtype: vtype, size: size}; + return { ktype: ktype, vtype: vtype, size: size }; }; -TBinaryProtocol.prototype.readMapEnd = function() { -}; +TBinaryProtocol.prototype.readMapEnd = function () {}; -TBinaryProtocol.prototype.readListBegin = function() { +TBinaryProtocol.prototype.readListBegin = function () { var etype = this.readByte(); var size = this.readI32(); - return {etype: etype, size: size}; + return { etype: etype, size: size }; }; -TBinaryProtocol.prototype.readListEnd = function() { -}; +TBinaryProtocol.prototype.readListEnd = function () {}; -TBinaryProtocol.prototype.readSetBegin = function() { +TBinaryProtocol.prototype.readSetBegin = function () { var etype = this.readByte(); var size = this.readI32(); - return {etype: etype, size: size}; + return { etype: etype, size: size }; }; -TBinaryProtocol.prototype.readSetEnd = function() { -}; +TBinaryProtocol.prototype.readSetEnd = function () {}; -TBinaryProtocol.prototype.readBool = function() { +TBinaryProtocol.prototype.readBool = function () { var b = this.readByte(); if (b === 0) { return false; @@ -255,56 +251,62 @@ TBinaryProtocol.prototype.readBool = function() { return true; }; -TBinaryProtocol.prototype.readByte = function() { +TBinaryProtocol.prototype.readByte = function () { return this.trans.readByte(); }; -TBinaryProtocol.prototype.readI16 = function() { +TBinaryProtocol.prototype.readI16 = function () { return this.trans.readI16(); }; -TBinaryProtocol.prototype.readI32 = function() { +TBinaryProtocol.prototype.readI32 = function () { return this.trans.readI32(); }; -TBinaryProtocol.prototype.readI64 = function() { +TBinaryProtocol.prototype.readI64 = function () { var buff = this.trans.read(8); return new Int64(buff); }; -TBinaryProtocol.prototype.readDouble = function() { +TBinaryProtocol.prototype.readDouble = function () { return this.trans.readDouble(); }; -TBinaryProtocol.prototype.readBinary = function() { +TBinaryProtocol.prototype.readBinary = function () { var len = this.readI32(); if (len === 0) { return new Buffer(0); } if (len < 0) { - throw new Thrift.TProtocolException(Thrift.TProtocolExceptionType.NEGATIVE_SIZE, "Negative binary size"); + throw new Thrift.TProtocolException( + Thrift.TProtocolExceptionType.NEGATIVE_SIZE, + "Negative binary size", + ); } return this.trans.read(len); }; -TBinaryProtocol.prototype.readString = function() { +TBinaryProtocol.prototype.readString = function () { var len = this.readI32(); if (len === 0) { return ""; } if (len < 0) { - throw new Thrift.TProtocolException(Thrift.TProtocolExceptionType.NEGATIVE_SIZE, "Negative string size"); + throw new Thrift.TProtocolException( + Thrift.TProtocolExceptionType.NEGATIVE_SIZE, + "Negative string size", + ); } return this.trans.readString(len); }; -TBinaryProtocol.prototype.getTransport = function() { +TBinaryProtocol.prototype.getTransport = function () { return this.trans; }; -TBinaryProtocol.prototype.skip = function(type) { +TBinaryProtocol.prototype.skip = function (type) { switch (type) { case Type.BOOL: this.readBool(); @@ -362,6 +364,6 @@ TBinaryProtocol.prototype.skip = function(type) { this.readListEnd(); break; default: - throw new Error("Invalid type: " + type); + throw new Error("Invalid type: " + type); } }; diff --git a/lib/nodejs/lib/thrift/browser.js b/lib/nodejs/lib/thrift/browser.js index e217704d66d..5c843d07137 100644 --- a/lib/nodejs/lib/thrift/browser.js +++ b/lib/nodejs/lib/thrift/browser.js @@ -16,38 +16,42 @@ * specific language governing permissions and limitations * under the License. */ -exports.Thrift = require('./thrift'); +exports.Thrift = require("./thrift"); -var wsConnection = require('./ws_connection'); +var wsConnection = require("./ws_connection"); exports.WSConnection = wsConnection.WSConnection; exports.createWSConnection = wsConnection.createWSConnection; exports.createWSClient = wsConnection.createWSClient; -var xhrConnection = require('./xhr_connection'); +var xhrConnection = require("./xhr_connection"); exports.XHRConnection = xhrConnection.XHRConnection; exports.createXHRConnection = xhrConnection.createXHRConnection; exports.createXHRClient = xhrConnection.createXHRClient; -var ohosConnection = require('./ohos_connection'); +var ohosConnection = require("./ohos_connection"); exports.OhosConnection = ohosConnection.OhosConnection; exports.createOhosConnection = ohosConnection.createOhosConnection; exports.createOhosClient = ohosConnection.createOhosClient; -exports.Int64 = require('node-int64'); -exports.Q = require('q'); +exports.createClient = require("./create_client"); -var mpxProtocol = require('./multiplexed_protocol'); +exports.Int64 = require("node-int64"); +exports.Q = require("q"); + +var mpxProtocol = require("./multiplexed_protocol"); exports.Multiplexer = mpxProtocol.Multiplexer; /* * Export transport and protocol so they can be used outside of a * cassandra/server context */ -exports.TBufferedTransport = require('./buffered_transport'); -exports.TFramedTransport = require('./framed_transport'); -exports.TWebSocketTransport = require('./ws_transport'); - -exports.Protocol = require('./json_protocol'); -exports.TJSONProtocol = require('./json_protocol'); -exports.TBinaryProtocol = require('./binary_protocol'); -exports.TCompactProtocol = require('./compact_protocol'); +exports.TBufferedTransport = require("./buffered_transport"); +exports.TFramedTransport = require("./framed_transport"); +exports.TWebSocketTransport = require("./ws_transport"); + +exports.Protocol = require("./json_protocol"); +exports.TJSONProtocol = require("./json_protocol"); +exports.TBinaryProtocol = require("./binary_protocol"); +exports.TCompactProtocol = require("./compact_protocol"); + +exports.InputBufferUnderrunError = require("./input_buffer_underrun_error"); diff --git a/lib/nodejs/lib/thrift/buffered_transport.js b/lib/nodejs/lib/thrift/buffered_transport.js index f0d5d4aa1e4..27d682d8fd0 100644 --- a/lib/nodejs/lib/thrift/buffered_transport.js +++ b/lib/nodejs/lib/thrift/buffered_transport.js @@ -17,9 +17,9 @@ * under the License. */ -var binary = require('./binary'); -var InputBufferUnderrunError = require('./input_buffer_underrun_error'); -var THeaderTransport = require('./header_transport'); +var binary = require("./binary"); +var InputBufferUnderrunError = require("./input_buffer_underrun_error"); +var THeaderTransport = require("./header_transport"); module.exports = TBufferedTransport; @@ -33,22 +33,22 @@ function TBufferedTransport(buffer, callback) { this.outBuffers = []; this.outCount = 0; this.onFlush = callback; -}; +} Object.setPrototypeOf(TBufferedTransport.prototype, THeaderTransport.prototype); -TBufferedTransport.prototype.reset = function() { +TBufferedTransport.prototype.reset = function () { this.inBuf = new Buffer(this.defaultReadBufferSize); this.readCursor = 0; this.writeCursor = 0; this.outBuffers = []; this.outCount = 0; -} +}; -TBufferedTransport.receiver = function(callback, seqid) { +TBufferedTransport.receiver = function (callback, seqid) { var reader = new TBufferedTransport(); - return function(data) { + return function (data) { if (reader.writeCursor + data.length > reader.inBuf.length) { var buf = new Buffer(reader.writeCursor + data.length); reader.inBuf.copy(buf, 0, 0, reader.writeCursor); @@ -61,11 +61,12 @@ TBufferedTransport.receiver = function(callback, seqid) { }; }; - -TBufferedTransport.prototype.commitPosition = function(){ +TBufferedTransport.prototype.commitPosition = function () { var unreadSize = this.writeCursor - this.readCursor; - var bufSize = (unreadSize * 2 > this.defaultReadBufferSize) ? - unreadSize * 2 : this.defaultReadBufferSize; + var bufSize = + unreadSize * 2 > this.defaultReadBufferSize + ? unreadSize * 2 + : this.defaultReadBufferSize; var buf = new Buffer(bufSize); if (unreadSize > 0) { this.inBuf.copy(buf, 0, this.readCursor, this.writeCursor); @@ -75,34 +76,32 @@ TBufferedTransport.prototype.commitPosition = function(){ this.inBuf = buf; }; -TBufferedTransport.prototype.rollbackPosition = function(){ +TBufferedTransport.prototype.rollbackPosition = function () { this.readCursor = 0; -} +}; - // TODO: Implement open/close support -TBufferedTransport.prototype.isOpen = function() { +// TODO: Implement open/close support +TBufferedTransport.prototype.isOpen = function () { return true; }; -TBufferedTransport.prototype.open = function() { -}; +TBufferedTransport.prototype.open = function () {}; -TBufferedTransport.prototype.close = function() { -}; +TBufferedTransport.prototype.close = function () {}; - // Set the seqid of the message in the client - // So that callbacks can be found -TBufferedTransport.prototype.setCurrSeqId = function(seqid) { +// Set the seqid of the message in the client +// So that callbacks can be found +TBufferedTransport.prototype.setCurrSeqId = function (seqid) { this._seqid = seqid; }; -TBufferedTransport.prototype.ensureAvailable = function(len) { +TBufferedTransport.prototype.ensureAvailable = function (len) { if (this.readCursor + len > this.writeCursor) { throw new InputBufferUnderrunError(); } }; -TBufferedTransport.prototype.read = function(len) { +TBufferedTransport.prototype.read = function (len) { this.ensureAvailable(len); var buf = new Buffer(len); this.inBuf.copy(buf, 0, this.readCursor, this.readCursor + len); @@ -110,57 +109,61 @@ TBufferedTransport.prototype.read = function(len) { return buf; }; -TBufferedTransport.prototype.readByte = function() { +TBufferedTransport.prototype.readByte = function () { this.ensureAvailable(1); return binary.readByte(this.inBuf[this.readCursor++]); }; -TBufferedTransport.prototype.readI16 = function() { +TBufferedTransport.prototype.readI16 = function () { this.ensureAvailable(2); var i16 = binary.readI16(this.inBuf, this.readCursor); this.readCursor += 2; return i16; }; -TBufferedTransport.prototype.readI32 = function() { +TBufferedTransport.prototype.readI32 = function () { this.ensureAvailable(4); var i32 = binary.readI32(this.inBuf, this.readCursor); this.readCursor += 4; return i32; }; -TBufferedTransport.prototype.readDouble = function() { +TBufferedTransport.prototype.readDouble = function () { this.ensureAvailable(8); var d = binary.readDouble(this.inBuf, this.readCursor); this.readCursor += 8; return d; }; -TBufferedTransport.prototype.readString = function(len) { +TBufferedTransport.prototype.readString = function (len) { this.ensureAvailable(len); - var str = this.inBuf.toString('utf8', this.readCursor, this.readCursor + len); + var str = this.inBuf.toString("utf8", this.readCursor, this.readCursor + len); this.readCursor += len; return str; }; -TBufferedTransport.prototype.borrow = function() { - var obj = {buf: this.inBuf, readIndex: this.readCursor, writeIndex: this.writeCursor}; +TBufferedTransport.prototype.borrow = function () { + var obj = { + buf: this.inBuf, + readIndex: this.readCursor, + writeIndex: this.writeCursor, + }; return obj; }; -TBufferedTransport.prototype.consume = function(bytesConsumed) { +TBufferedTransport.prototype.consume = function (bytesConsumed) { this.readCursor += bytesConsumed; }; -TBufferedTransport.prototype.write = function(buf) { - if (typeof(buf) === "string") { - buf = new Buffer(buf, 'utf8'); +TBufferedTransport.prototype.write = function (buf) { + if (typeof buf === "string") { + buf = new Buffer(buf, "utf8"); } this.outBuffers.push(buf); this.outCount += buf.length; }; -TBufferedTransport.prototype.flush = function() { +TBufferedTransport.prototype.flush = function () { // If the seqid of the callback is available pass it to the onFlush // Then remove the current seqid var seqid = this._seqid; @@ -171,8 +174,8 @@ TBufferedTransport.prototype.flush = function() { } var msg = new Buffer(this.outCount), - pos = 0; - this.outBuffers.forEach(function(buf) { + pos = 0; + this.outBuffers.forEach(function (buf) { buf.copy(msg, pos, 0); pos += buf.length; }); @@ -184,4 +187,4 @@ TBufferedTransport.prototype.flush = function() { this.outBuffers = []; this.outCount = 0; -} +}; diff --git a/lib/nodejs/lib/thrift/compact_protocol.js b/lib/nodejs/lib/thrift/compact_protocol.js index 302a88d4d84..e946dc886c0 100644 --- a/lib/nodejs/lib/thrift/compact_protocol.js +++ b/lib/nodejs/lib/thrift/compact_protocol.js @@ -17,9 +17,9 @@ * under the License. */ -var log = require('./log'); -var Int64 = require('node-int64'); -var Thrift = require('./thrift'); +var log = require("./log"); +var Int64 = require("node-int64"); +var Thrift = require("./thrift"); var Type = Thrift.Type; module.exports = TCompactProtocol; @@ -50,59 +50,58 @@ function TCompactProtocol(trans) { this.container_limit_ = 0; this.booleanField_ = { name: null, - hasBoolValue: false + hasBoolValue: false, }; this.boolValue_ = { hasBoolValue: false, - boolValue: false + boolValue: false, }; -}; - +} // // Compact Protocol Constants // /** - * Compact Protocol ID number. - * @readonly - * @const {number} PROTOCOL_ID - */ -TCompactProtocol.PROTOCOL_ID = -126; //1000 0010 + * Compact Protocol ID number. + * @readonly + * @const {number} PROTOCOL_ID + */ +TCompactProtocol.PROTOCOL_ID = -126; //1000 0010 /** - * Compact Protocol version number. - * @readonly - * @const {number} VERSION_N - */ + * Compact Protocol version number. + * @readonly + * @const {number} VERSION_N + */ TCompactProtocol.VERSION_N = 1; /** - * Compact Protocol version mask for combining protocol version and message type in one byte. - * @readonly - * @const {number} VERSION_MASK - */ + * Compact Protocol version mask for combining protocol version and message type in one byte. + * @readonly + * @const {number} VERSION_MASK + */ TCompactProtocol.VERSION_MASK = 0x1f; //0001 1111 /** - * Compact Protocol message type mask for combining protocol version and message type in one byte. - * @readonly - * @const {number} TYPE_MASK - */ -TCompactProtocol.TYPE_MASK = -32; //1110 0000 + * Compact Protocol message type mask for combining protocol version and message type in one byte. + * @readonly + * @const {number} TYPE_MASK + */ +TCompactProtocol.TYPE_MASK = -32; //1110 0000 /** - * Compact Protocol message type bits for ensuring message type bit size. - * @readonly - * @const {number} TYPE_BITS - */ + * Compact Protocol message type bits for ensuring message type bit size. + * @readonly + * @const {number} TYPE_BITS + */ TCompactProtocol.TYPE_BITS = 7; //0000 0111 /** - * Compact Protocol message type shift amount for combining protocol version and message type in one byte. - * @readonly - * @const {number} TYPE_SHIFT_AMOUNT - */ + * Compact Protocol message type shift amount for combining protocol version and message type in one byte. + * @readonly + * @const {number} TYPE_SHIFT_AMOUNT + */ TCompactProtocol.TYPE_SHIFT_AMOUNT = 5; /** @@ -123,19 +122,19 @@ TCompactProtocol.TYPE_SHIFT_AMOUNT = 5; * @property {number} CT_STRUCT - A multifield type. */ TCompactProtocol.Types = { - CT_STOP: 0x00, - CT_BOOLEAN_TRUE: 0x01, - CT_BOOLEAN_FALSE: 0x02, - CT_BYTE: 0x03, - CT_I16: 0x04, - CT_I32: 0x05, - CT_I64: 0x06, - CT_DOUBLE: 0x07, - CT_BINARY: 0x08, - CT_LIST: 0x09, - CT_SET: 0x0A, - CT_MAP: 0x0B, - CT_STRUCT: 0x0C + CT_STOP: 0x00, + CT_BOOLEAN_TRUE: 0x01, + CT_BOOLEAN_FALSE: 0x02, + CT_BYTE: 0x03, + CT_I16: 0x04, + CT_I32: 0x05, + CT_I64: 0x06, + CT_DOUBLE: 0x07, + CT_BINARY: 0x08, + CT_LIST: 0x09, + CT_SET: 0x0a, + CT_MAP: 0x0b, + CT_STRUCT: 0x0c, }; /** @@ -143,25 +142,24 @@ TCompactProtocol.Types = { * @readonly */ TCompactProtocol.TTypeToCType = [ - TCompactProtocol.Types.CT_STOP, // T_STOP - 0, // unused + TCompactProtocol.Types.CT_STOP, // T_STOP + 0, // unused TCompactProtocol.Types.CT_BOOLEAN_TRUE, // T_BOOL - TCompactProtocol.Types.CT_BYTE, // T_BYTE - TCompactProtocol.Types.CT_DOUBLE, // T_DOUBLE - 0, // unused - TCompactProtocol.Types.CT_I16, // T_I16 - 0, // unused - TCompactProtocol.Types.CT_I32, // T_I32 - 0, // unused - TCompactProtocol.Types.CT_I64, // T_I64 - TCompactProtocol.Types.CT_BINARY, // T_STRING - TCompactProtocol.Types.CT_STRUCT, // T_STRUCT - TCompactProtocol.Types.CT_MAP, // T_MAP - TCompactProtocol.Types.CT_SET, // T_SET - TCompactProtocol.Types.CT_LIST, // T_LIST + TCompactProtocol.Types.CT_BYTE, // T_BYTE + TCompactProtocol.Types.CT_DOUBLE, // T_DOUBLE + 0, // unused + TCompactProtocol.Types.CT_I16, // T_I16 + 0, // unused + TCompactProtocol.Types.CT_I32, // T_I32 + 0, // unused + TCompactProtocol.Types.CT_I64, // T_I64 + TCompactProtocol.Types.CT_BINARY, // T_STRING + TCompactProtocol.Types.CT_STRUCT, // T_STRUCT + TCompactProtocol.Types.CT_MAP, // T_MAP + TCompactProtocol.Types.CT_SET, // T_SET + TCompactProtocol.Types.CT_LIST, // T_LIST ]; - // // Compact Protocol Utilities // @@ -169,7 +167,7 @@ TCompactProtocol.TTypeToCType = [ /** * Returns the underlying transport layer. * @return {object} The underlying transport layer. - */TCompactProtocol.prototype.getTransport = function() { + */ TCompactProtocol.prototype.getTransport = function () { return this.trans; }; @@ -179,7 +177,7 @@ TCompactProtocol.TTypeToCType = [ * @param {number} ttype - Thrift type value * @returns {number} Compact protocol type value */ -TCompactProtocol.prototype.getCompactType = function(ttype) { +TCompactProtocol.prototype.getCompactType = function (ttype) { return TCompactProtocol.TTypeToCType[ttype]; }; @@ -189,7 +187,7 @@ TCompactProtocol.prototype.getCompactType = function(ttype) { * @param {number} type - Compact Protocol type value * @returns {number} Thrift Type value */ -TCompactProtocol.prototype.getTType = function(type) { +TCompactProtocol.prototype.getTType = function (type) { switch (type) { case Type.STOP: return Type.STOP; @@ -217,12 +215,14 @@ TCompactProtocol.prototype.getTType = function(type) { case TCompactProtocol.Types.CT_STRUCT: return Type.STRUCT; default: - throw new Thrift.TProtocolException(Thrift.TProtocolExceptionType.INVALID_DATA, "Unknown type: " + type); + throw new Thrift.TProtocolException( + Thrift.TProtocolExceptionType.INVALID_DATA, + "Unknown type: " + type, + ); } return Type.STOP; }; - // // Compact Protocol write operations // @@ -230,7 +230,7 @@ TCompactProtocol.prototype.getTType = function(type) { /** * Send any buffered bytes to the end point. */ -TCompactProtocol.prototype.flush = function() { +TCompactProtocol.prototype.flush = function () { return this.trans.flush(); }; @@ -240,31 +240,33 @@ TCompactProtocol.prototype.flush = function() { * @param {number} type - The type of message (CALL, REPLY, EXCEPTION, ONEWAY). * @param {number} seqid - The call sequence number (if any). */ -TCompactProtocol.prototype.writeMessageBegin = function(name, type, seqid) { +TCompactProtocol.prototype.writeMessageBegin = function (name, type, seqid) { this.writeByte(TCompactProtocol.PROTOCOL_ID); - this.writeByte((TCompactProtocol.VERSION_N & TCompactProtocol.VERSION_MASK) | - ((type << TCompactProtocol.TYPE_SHIFT_AMOUNT) & TCompactProtocol.TYPE_MASK)); + this.writeByte( + (TCompactProtocol.VERSION_N & TCompactProtocol.VERSION_MASK) | + ((type << TCompactProtocol.TYPE_SHIFT_AMOUNT) & + TCompactProtocol.TYPE_MASK), + ); this.writeVarint32(seqid); this.writeString(name); // Record client seqid to find callback again if (this._seqid) { - log.warning('SeqId already set', { 'name': name }); + log.warning("SeqId already set", { name: name }); } else { this._seqid = seqid; this.trans.setCurrSeqId(seqid); } }; -TCompactProtocol.prototype.writeMessageEnd = function() { -}; +TCompactProtocol.prototype.writeMessageEnd = function () {}; -TCompactProtocol.prototype.writeStructBegin = function(name) { +TCompactProtocol.prototype.writeStructBegin = function (name) { this.lastField_.push(this.lastFieldId_); this.lastFieldId_ = 0; }; -TCompactProtocol.prototype.writeStructEnd = function() { +TCompactProtocol.prototype.writeStructEnd = function () { this.lastFieldId_ = this.lastField_.pop(); }; @@ -274,7 +276,7 @@ TCompactProtocol.prototype.writeStructEnd = function() { * @param {number} type - The field data type (a normal Thrift field Type). * @param {number} id - The IDL field Id. */ -TCompactProtocol.prototype.writeFieldBegin = function(name, type, id) { +TCompactProtocol.prototype.writeFieldBegin = function (name, type, id) { if (type != Type.BOOL) { return this.writeFieldBeginInternal(name, type, id, -1); } @@ -284,10 +286,9 @@ TCompactProtocol.prototype.writeFieldBegin = function(name, type, id) { this.booleanField_.fieldId = id; }; -TCompactProtocol.prototype.writeFieldEnd = function() { -}; +TCompactProtocol.prototype.writeFieldEnd = function () {}; -TCompactProtocol.prototype.writeFieldStop = function() { +TCompactProtocol.prototype.writeFieldStop = function () { this.writeByte(TCompactProtocol.Types.CT_STOP); }; @@ -297,80 +298,85 @@ TCompactProtocol.prototype.writeFieldStop = function() { * @param {number} valType - The Thrift type of the map values. * @param {number} size - The number of k/v pairs in the map. */ -TCompactProtocol.prototype.writeMapBegin = function(keyType, valType, size) { +TCompactProtocol.prototype.writeMapBegin = function (keyType, valType, size) { if (size === 0) { this.writeByte(0); } else { this.writeVarint32(size); - this.writeByte(this.getCompactType(keyType) << 4 | this.getCompactType(valType)); + this.writeByte( + (this.getCompactType(keyType) << 4) | this.getCompactType(valType), + ); } }; -TCompactProtocol.prototype.writeMapEnd = function() { -}; +TCompactProtocol.prototype.writeMapEnd = function () {}; /** * Writes a list collection header * @param {number} elemType - The Thrift type of the list elements. * @param {number} size - The number of elements in the list. */ -TCompactProtocol.prototype.writeListBegin = function(elemType, size) { +TCompactProtocol.prototype.writeListBegin = function (elemType, size) { this.writeCollectionBegin(elemType, size); }; -TCompactProtocol.prototype.writeListEnd = function() { -}; +TCompactProtocol.prototype.writeListEnd = function () {}; /** * Writes a set collection header * @param {number} elemType - The Thrift type of the set elements. * @param {number} size - The number of elements in the set. */ -TCompactProtocol.prototype.writeSetBegin = function(elemType, size) { +TCompactProtocol.prototype.writeSetBegin = function (elemType, size) { this.writeCollectionBegin(elemType, size); }; -TCompactProtocol.prototype.writeSetEnd = function() { -}; +TCompactProtocol.prototype.writeSetEnd = function () {}; -TCompactProtocol.prototype.writeBool = function(value) { +TCompactProtocol.prototype.writeBool = function (value) { if (this.booleanField_.name !== null) { // we haven't written the field header yet - this.writeFieldBeginInternal(this.booleanField_.name, - this.booleanField_.fieldType, - this.booleanField_.fieldId, - (value ? TCompactProtocol.Types.CT_BOOLEAN_TRUE - : TCompactProtocol.Types.CT_BOOLEAN_FALSE)); + this.writeFieldBeginInternal( + this.booleanField_.name, + this.booleanField_.fieldType, + this.booleanField_.fieldId, + value + ? TCompactProtocol.Types.CT_BOOLEAN_TRUE + : TCompactProtocol.Types.CT_BOOLEAN_FALSE, + ); this.booleanField_.name = null; } else { // we're not part of a field, so just write the value - this.writeByte((value ? TCompactProtocol.Types.CT_BOOLEAN_TRUE - : TCompactProtocol.Types.CT_BOOLEAN_FALSE)); + this.writeByte( + value + ? TCompactProtocol.Types.CT_BOOLEAN_TRUE + : TCompactProtocol.Types.CT_BOOLEAN_FALSE, + ); } }; -TCompactProtocol.prototype.writeByte = function(b) { +TCompactProtocol.prototype.writeByte = function (b) { this.trans.write(new Buffer([b])); }; -TCompactProtocol.prototype.writeI16 = function(i16) { +TCompactProtocol.prototype.writeI16 = function (i16) { this.writeVarint32(this.i32ToZigzag(i16)); }; -TCompactProtocol.prototype.writeI32 = function(i32) { +TCompactProtocol.prototype.writeI32 = function (i32) { this.writeVarint32(this.i32ToZigzag(i32)); }; -TCompactProtocol.prototype.writeI64 = function(i64) { +TCompactProtocol.prototype.writeI64 = function (i64) { this.writeVarint64(this.i64ToZigzag(i64)); }; // Little-endian, unlike TBinaryProtocol -TCompactProtocol.prototype.writeDouble = function(v) { +TCompactProtocol.prototype.writeDouble = function (v) { var buff = new Buffer(8); var m, e, c; - buff[7] = (v < 0 ? 0x80 : 0x00); + buff[7] = v < 0 ? 0x80 : 0x00; v = Math.abs(v); if (v !== v) { @@ -388,22 +394,17 @@ TCompactProtocol.prototype.writeDouble = function(v) { c *= 2; } - if (e + 1023 >= 2047) - { + if (e + 1023 >= 2047) { // Overflow m = 0; e = 2047; - } - else if (e + 1023 >= 1) - { + } else if (e + 1023 >= 1) { // Normalized - term order matters, as Math.pow(2, 52-e) and v*Math.pow(2, 52) can overflow - m = (v*c-1) * POW_52; + m = (v * c - 1) * POW_52; e += 1023; - } - else - { + } else { // Denormalized - also catches the '0' case, somewhat by chance - m = (v * POW_1022) * POW_52; + m = v * POW_1022 * POW_52; e = 0; } } @@ -428,45 +429,53 @@ TCompactProtocol.prototype.writeDouble = function(v) { this.trans.write(buff); }; -TCompactProtocol.prototype.writeStringOrBinary = function(name, encoding, arg) { - if (typeof arg === 'string') { - this.writeVarint32(Buffer.byteLength(arg, encoding)) ; +TCompactProtocol.prototype.writeStringOrBinary = function ( + name, + encoding, + arg, +) { + if (typeof arg === "string") { + this.writeVarint32(Buffer.byteLength(arg, encoding)); this.trans.write(new Buffer(arg, encoding)); - } else if (arg instanceof Buffer || - Object.prototype.toString.call(arg) == '[object Uint8Array]') { + } else if ( + arg instanceof Buffer || + Object.prototype.toString.call(arg) == "[object Uint8Array]" + ) { // Buffers in Node.js under Browserify may extend UInt8Array instead of // defining a new object. We detect them here so we can write them // correctly this.writeVarint32(arg.length); this.trans.write(arg); } else { - throw new Error(name + ' called without a string/Buffer argument: ' + arg); + throw new Error(name + " called without a string/Buffer argument: " + arg); } }; -TCompactProtocol.prototype.writeString = function(arg) { - this.writeStringOrBinary('writeString', 'utf8', arg); +TCompactProtocol.prototype.writeString = function (arg) { + this.writeStringOrBinary("writeString", "utf8", arg); }; -TCompactProtocol.prototype.writeBinary = function(arg) { - this.writeStringOrBinary('writeBinary', 'binary', arg); +TCompactProtocol.prototype.writeBinary = function (arg) { + this.writeStringOrBinary("writeBinary", "binary", arg); }; - // // Compact Protocol internal write methods // -TCompactProtocol.prototype.writeFieldBeginInternal = function(name, - fieldType, - fieldId, - typeOverride) { +TCompactProtocol.prototype.writeFieldBeginInternal = function ( + name, + fieldType, + fieldId, + typeOverride, +) { //If there's a type override, use that. - var typeToWrite = (typeOverride == -1 ? this.getCompactType(fieldType) : typeOverride); + var typeToWrite = + typeOverride == -1 ? this.getCompactType(fieldType) : typeOverride; //Check if we can delta encode the field id if (fieldId > this.lastFieldId_ && fieldId - this.lastFieldId_ <= 15) { //Include the type delta with the field ID - this.writeByte((fieldId - this.lastFieldId_) << 4 | typeToWrite); + this.writeByte(((fieldId - this.lastFieldId_) << 4) | typeToWrite); } else { //Write separate type and ID values this.writeByte(typeToWrite); @@ -475,10 +484,10 @@ TCompactProtocol.prototype.writeFieldBeginInternal = function(name, this.lastFieldId_ = fieldId; }; -TCompactProtocol.prototype.writeCollectionBegin = function(elemType, size) { +TCompactProtocol.prototype.writeCollectionBegin = function (elemType, size) { if (size <= 14) { //Combine size and type in one byte if possible - this.writeByte(size << 4 | this.getCompactType(elemType)); + this.writeByte((size << 4) | this.getCompactType(elemType)); } else { this.writeByte(0xf0 | this.getCompactType(elemType)); this.writeVarint32(size); @@ -488,20 +497,20 @@ TCompactProtocol.prototype.writeCollectionBegin = function(elemType, size) { /** * Write an i32 as a varint. Results in 1-5 bytes on the wire. */ -TCompactProtocol.prototype.writeVarint32 = function(n) { +TCompactProtocol.prototype.writeVarint32 = function (n) { var buf = new Buffer(5); var wsize = 0; while (true) { - if ((n & ~0x7F) === 0) { + if ((n & ~0x7f) === 0) { buf[wsize++] = n; break; } else { - buf[wsize++] = ((n & 0x7F) | 0x80); + buf[wsize++] = (n & 0x7f) | 0x80; n = n >>> 7; } } var wbuf = new Buffer(wsize); - buf.copy(wbuf,0,0,wsize); + buf.copy(wbuf, 0, 0, wsize); this.trans.write(wbuf); }; @@ -509,12 +518,15 @@ TCompactProtocol.prototype.writeVarint32 = function(n) { * Write an i64 as a varint. Results in 1-10 bytes on the wire. * N.B. node-int64 is always big endian */ -TCompactProtocol.prototype.writeVarint64 = function(n) { - if (typeof n === "number"){ +TCompactProtocol.prototype.writeVarint64 = function (n) { + if (typeof n === "number") { n = new Int64(n); } - if (! (n instanceof Int64)) { - throw new Thrift.TProtocolException(Thrift.TProtocolExceptionType.INVALID_DATA, "Expected Int64 or Number, found: " + n); + if (!(n instanceof Int64)) { + throw new Thrift.TProtocolException( + Thrift.TProtocolExceptionType.INVALID_DATA, + "Expected Int64 or Number, found: " + n, + ); } var buf = new Buffer(10); @@ -523,11 +535,11 @@ TCompactProtocol.prototype.writeVarint64 = function(n) { var lo = n.buffer.readUInt32BE(4, true); var mask = 0; while (true) { - if (((lo & ~0x7F) === 0) && (hi === 0)) { + if ((lo & ~0x7f) === 0 && hi === 0) { buf[wsize++] = lo; break; } else { - buf[wsize++] = ((lo & 0x7F) | 0x80); + buf[wsize++] = (lo & 0x7f) | 0x80; mask = hi << 25; lo = lo >>> 7; hi = hi >>> 7; @@ -535,7 +547,7 @@ TCompactProtocol.prototype.writeVarint64 = function(n) { } } var wbuf = new Buffer(wsize); - buf.copy(wbuf,0,0,wsize); + buf.copy(wbuf, 0, 0, wsize); this.trans.write(wbuf); }; @@ -543,20 +555,23 @@ TCompactProtocol.prototype.writeVarint64 = function(n) { * Convert l into a zigzag long. This allows negative numbers to be * represented compactly as a varint. */ -TCompactProtocol.prototype.i64ToZigzag = function(l) { - if (typeof l === 'string') { +TCompactProtocol.prototype.i64ToZigzag = function (l) { + if (typeof l === "string") { l = new Int64(parseInt(l, 10)); - } else if (typeof l === 'number') { + } else if (typeof l === "number") { l = new Int64(l); } - if (! (l instanceof Int64)) { - throw new Thrift.TProtocolException(Thrift.TProtocolExceptionType.INVALID_DATA, "Expected Int64 or Number, found: " + l); + if (!(l instanceof Int64)) { + throw new Thrift.TProtocolException( + Thrift.TProtocolExceptionType.INVALID_DATA, + "Expected Int64 or Number, found: " + l, + ); } var hi = l.buffer.readUInt32BE(0, true); var lo = l.buffer.readUInt32BE(4, true); var sign = hi >>> 31; - hi = ((hi << 1) | (lo >>> 31)) ^ ((!!sign) ? 0xFFFFFFFF : 0); - lo = (lo << 1) ^ ((!!sign) ? 0xFFFFFFFF : 0); + hi = ((hi << 1) | (lo >>> 31)) ^ (!!sign ? 0xffffffff : 0); + lo = (lo << 1) ^ (!!sign ? 0xffffffff : 0); return new Int64(hi, lo); }; @@ -564,29 +579,36 @@ TCompactProtocol.prototype.i64ToZigzag = function(l) { * Convert n into a zigzag int. This allows negative numbers to be * represented compactly as a varint. */ -TCompactProtocol.prototype.i32ToZigzag = function(n) { - return (n << 1) ^ ((n & 0x80000000) ? 0xFFFFFFFF : 0); +TCompactProtocol.prototype.i32ToZigzag = function (n) { + return (n << 1) ^ (n & 0x80000000 ? 0xffffffff : 0); }; - // // Compact Protocol read operations // -TCompactProtocol.prototype.readMessageBegin = function() { +TCompactProtocol.prototype.readMessageBegin = function () { //Read protocol ID var protocolId = this.trans.readByte(); if (protocolId != TCompactProtocol.PROTOCOL_ID) { - throw new Thrift.TProtocolException(Thrift.TProtocolExceptionType.BAD_VERSION, "Bad protocol identifier " + protocolId); + throw new Thrift.TProtocolException( + Thrift.TProtocolExceptionType.BAD_VERSION, + "Bad protocol identifier " + protocolId, + ); } //Read Version and Type var versionAndType = this.trans.readByte(); - var version = (versionAndType & TCompactProtocol.VERSION_MASK); + var version = versionAndType & TCompactProtocol.VERSION_MASK; if (version != TCompactProtocol.VERSION_N) { - throw new Thrift.TProtocolException(Thrift.TProtocolExceptionType.BAD_VERSION, "Bad protocol version " + version); + throw new Thrift.TProtocolException( + Thrift.TProtocolExceptionType.BAD_VERSION, + "Bad protocol version " + version, + ); } - var type = ((versionAndType >> TCompactProtocol.TYPE_SHIFT_AMOUNT) & TCompactProtocol.TYPE_BITS); + var type = + (versionAndType >> TCompactProtocol.TYPE_SHIFT_AMOUNT) & + TCompactProtocol.TYPE_BITS; //Read SeqId var seqid = this.readVarint32(); @@ -594,62 +616,65 @@ TCompactProtocol.prototype.readMessageBegin = function() { //Read name var name = this.readString(); - return {fname: name, mtype: type, rseqid: seqid}; + return { fname: name, mtype: type, rseqid: seqid }; }; -TCompactProtocol.prototype.readMessageEnd = function() { -}; +TCompactProtocol.prototype.readMessageEnd = function () {}; -TCompactProtocol.prototype.readStructBegin = function() { +TCompactProtocol.prototype.readStructBegin = function () { this.lastField_.push(this.lastFieldId_); this.lastFieldId_ = 0; - return {fname: ''}; + return { fname: "" }; }; -TCompactProtocol.prototype.readStructEnd = function() { +TCompactProtocol.prototype.readStructEnd = function () { this.lastFieldId_ = this.lastField_.pop(); }; -TCompactProtocol.prototype.readFieldBegin = function() { +TCompactProtocol.prototype.readFieldBegin = function () { var fieldId = 0; var b = this.trans.readByte(b); - var type = (b & 0x0f); + var type = b & 0x0f; if (type == TCompactProtocol.Types.CT_STOP) { - return {fname: null, ftype: Thrift.Type.STOP, fid: 0}; + return { fname: null, ftype: Thrift.Type.STOP, fid: 0 }; } //Mask off the 4 MSB of the type header to check for field id delta. - var modifier = ((b & 0x000000f0) >>> 4); + var modifier = (b & 0x000000f0) >>> 4; if (modifier === 0) { //If not a delta read the field id. fieldId = this.readI16(); } else { //Recover the field id from the delta - fieldId = (this.lastFieldId_ + modifier); + fieldId = this.lastFieldId_ + modifier; } var fieldType = this.getTType(type); //Boolean are encoded with the type - if (type == TCompactProtocol.Types.CT_BOOLEAN_TRUE || - type == TCompactProtocol.Types.CT_BOOLEAN_FALSE) { + if ( + type == TCompactProtocol.Types.CT_BOOLEAN_TRUE || + type == TCompactProtocol.Types.CT_BOOLEAN_FALSE + ) { this.boolValue_.hasBoolValue = true; this.boolValue_.boolValue = - (type == TCompactProtocol.Types.CT_BOOLEAN_TRUE ? true : false); + type == TCompactProtocol.Types.CT_BOOLEAN_TRUE ? true : false; } //Save the new field for the next delta computation. this.lastFieldId_ = fieldId; - return {fname: null, ftype: fieldType, fid: fieldId}; + return { fname: null, ftype: fieldType, fid: fieldId }; }; -TCompactProtocol.prototype.readFieldEnd = function() { -}; +TCompactProtocol.prototype.readFieldEnd = function () {}; -TCompactProtocol.prototype.readMapBegin = function() { +TCompactProtocol.prototype.readMapBegin = function () { var msize = this.readVarint32(); if (msize < 0) { - throw new Thrift.TProtocolException(Thrift.TProtocolExceptionType.NEGATIVE_SIZE, "Negative map size"); + throw new Thrift.TProtocolException( + Thrift.TProtocolExceptionType.NEGATIVE_SIZE, + "Negative map size", + ); } var kvType = 0; @@ -659,13 +684,12 @@ TCompactProtocol.prototype.readMapBegin = function() { var keyType = this.getTType((kvType & 0xf0) >>> 4); var valType = this.getTType(kvType & 0xf); - return {ktype: keyType, vtype: valType, size: msize}; + return { ktype: keyType, vtype: valType, size: msize }; }; -TCompactProtocol.prototype.readMapEnd = function() { -}; +TCompactProtocol.prototype.readMapEnd = function () {}; -TCompactProtocol.prototype.readListBegin = function() { +TCompactProtocol.prototype.readListBegin = function () { var size_and_type = this.trans.readByte(); var lsize = (size_and_type >>> 4) & 0x0000000f; @@ -674,25 +698,26 @@ TCompactProtocol.prototype.readListBegin = function() { } if (lsize < 0) { - throw new Thrift.TProtocolException(Thrift.TProtocolExceptionType.NEGATIVE_SIZE, "Negative list size"); + throw new Thrift.TProtocolException( + Thrift.TProtocolExceptionType.NEGATIVE_SIZE, + "Negative list size", + ); } var elemType = this.getTType(size_and_type & 0x0000000f); - return {etype: elemType, size: lsize}; + return { etype: elemType, size: lsize }; }; -TCompactProtocol.prototype.readListEnd = function() { -}; +TCompactProtocol.prototype.readListEnd = function () {}; -TCompactProtocol.prototype.readSetBegin = function() { +TCompactProtocol.prototype.readSetBegin = function () { return this.readListBegin(); }; -TCompactProtocol.prototype.readSetEnd = function() { -}; +TCompactProtocol.prototype.readSetEnd = function () {}; -TCompactProtocol.prototype.readBool = function() { +TCompactProtocol.prototype.readBool = function () { var value = false; var rsize = 0; if (this.boolValue_.hasBoolValue === true) { @@ -701,50 +726,50 @@ TCompactProtocol.prototype.readBool = function() { } else { var res = this.trans.readByte(); rsize = res.rsize; - value = (res.value == TCompactProtocol.Types.CT_BOOLEAN_TRUE); + value = res.value == TCompactProtocol.Types.CT_BOOLEAN_TRUE; } return value; }; -TCompactProtocol.prototype.readByte = function() { +TCompactProtocol.prototype.readByte = function () { return this.trans.readByte(); }; -TCompactProtocol.prototype.readI16 = function() { +TCompactProtocol.prototype.readI16 = function () { return this.readI32(); }; -TCompactProtocol.prototype.readI32 = function() { +TCompactProtocol.prototype.readI32 = function () { return this.zigzagToI32(this.readVarint32()); }; -TCompactProtocol.prototype.readI64 = function() { +TCompactProtocol.prototype.readI64 = function () { return this.zigzagToI64(this.readVarint64()); }; // Little-endian, unlike TBinaryProtocol -TCompactProtocol.prototype.readDouble = function() { +TCompactProtocol.prototype.readDouble = function () { var buff = this.trans.read(8); var off = 0; var signed = buff[off + 7] & 0x80; - var e = (buff[off+6] & 0xF0) >> 4; - e += (buff[off+7] & 0x7F) << 4; + var e = (buff[off + 6] & 0xf0) >> 4; + e += (buff[off + 7] & 0x7f) << 4; var m = buff[off]; - m += buff[off+1] << 8; - m += buff[off+2] << 16; - m += buff[off+3] * POW_24; - m += buff[off+4] * POW_32; - m += buff[off+5] * POW_40; - m += (buff[off+6] & 0x0F) * POW_48; + m += buff[off + 1] << 8; + m += buff[off + 2] << 16; + m += buff[off + 3] * POW_24; + m += buff[off + 4] * POW_32; + m += buff[off + 5] * POW_40; + m += (buff[off + 6] & 0x0f) * POW_48; switch (e) { case 0: e = -1022; break; case 2047: - return m ? NaN : (signed ? -Infinity : Infinity); + return m ? NaN : signed ? -Infinity : Infinity; default: m += POW_52; e -= 1023; @@ -757,19 +782,22 @@ TCompactProtocol.prototype.readDouble = function() { return m * Math.pow(2, e - 52); }; -TCompactProtocol.prototype.readBinary = function() { +TCompactProtocol.prototype.readBinary = function () { var size = this.readVarint32(); if (size === 0) { return new Buffer(0); } if (size < 0) { - throw new Thrift.TProtocolException(Thrift.TProtocolExceptionType.NEGATIVE_SIZE, "Negative binary size"); + throw new Thrift.TProtocolException( + Thrift.TProtocolExceptionType.NEGATIVE_SIZE, + "Negative binary size", + ); } return this.trans.read(size); }; -TCompactProtocol.prototype.readString = function() { +TCompactProtocol.prototype.readString = function () { var size = this.readVarint32(); // Catch empty string case if (size === 0) { @@ -778,12 +806,14 @@ TCompactProtocol.prototype.readString = function() { // Catch error cases if (size < 0) { - throw new Thrift.TProtocolException(Thrift.TProtocolExceptionType.NEGATIVE_SIZE, "Negative string size"); + throw new Thrift.TProtocolException( + Thrift.TProtocolExceptionType.NEGATIVE_SIZE, + "Negative string size", + ); } return this.trans.readString(size); }; - // // Compact Protocol internal read operations // @@ -792,7 +822,7 @@ TCompactProtocol.prototype.readString = function() { * 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. */ -TCompactProtocol.prototype.readVarint32 = function() { +TCompactProtocol.prototype.readVarint32 = function () { return this.readVarint64().toNumber(); }; @@ -800,28 +830,31 @@ TCompactProtocol.prototype.readVarint32 = function() { * 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. */ -TCompactProtocol.prototype.readVarint64 = function() { +TCompactProtocol.prototype.readVarint64 = function () { var rsize = 0; var lo = 0; var hi = 0; var shift = 0; while (true) { var b = this.trans.readByte(); - rsize ++; + rsize++; if (shift <= 25) { lo = lo | ((b & 0x7f) << shift); } else if (25 < shift && shift < 32) { lo = lo | ((b & 0x7f) << shift); - hi = hi | ((b & 0x7f) >>> (32-shift)); + hi = hi | ((b & 0x7f) >>> (32 - shift)); } else { - hi = hi | ((b & 0x7f) << (shift-32)); + hi = hi | ((b & 0x7f) << (shift - 32)); } shift += 7; if (!(b & 0x80)) { break; } if (rsize >= 10) { - throw new Thrift.TProtocolException(Thrift.TProtocolExceptionType.INVALID_DATA, "Variable-length int over 10 bytes."); + throw new Thrift.TProtocolException( + Thrift.TProtocolExceptionType.INVALID_DATA, + "Variable-length int over 10 bytes.", + ); } } return new Int64(hi, lo); @@ -830,14 +863,14 @@ TCompactProtocol.prototype.readVarint64 = function() { /** * Convert from zigzag int to int. */ -TCompactProtocol.prototype.zigzagToI32 = function(n) { +TCompactProtocol.prototype.zigzagToI32 = function (n) { return (n >>> 1) ^ (-1 * (n & 1)); }; /** * Convert from zigzag long to long. */ -TCompactProtocol.prototype.zigzagToI64 = function(n) { +TCompactProtocol.prototype.zigzagToI64 = function (n) { var hi = n.buffer.readUInt32BE(0, true); var lo = n.buffer.readUInt32BE(4, true); @@ -846,13 +879,13 @@ TCompactProtocol.prototype.zigzagToI64 = function(n) { var hi_neg = neg.buffer.readUInt32BE(0, true); var lo_neg = neg.buffer.readUInt32BE(4, true); - var hi_lo = (hi << 31); - hi = (hi >>> 1) ^ (hi_neg); - lo = ((lo >>> 1) | hi_lo) ^ (lo_neg); + var hi_lo = hi << 31; + hi = (hi >>> 1) ^ hi_neg; + lo = ((lo >>> 1) | hi_lo) ^ lo_neg; return new Int64(hi, lo); }; -TCompactProtocol.prototype.skip = function(type) { +TCompactProtocol.prototype.skip = function (type) { switch (type) { case Type.BOOL: this.readBool(); @@ -910,6 +943,6 @@ TCompactProtocol.prototype.skip = function(type) { this.readListEnd(); break; default: - throw new Error("Invalid type: " + type); + throw new Error("Invalid type: " + type); } }; diff --git a/lib/nodejs/lib/thrift/connection.js b/lib/nodejs/lib/thrift/connection.js index b4e5a05277d..dcade80dc88 100644 --- a/lib/nodejs/lib/thrift/connection.js +++ b/lib/nodejs/lib/thrift/connection.js @@ -16,29 +16,29 @@ * specific language governing permissions and limitations * under the License. */ -var util = require('util'); -var EventEmitter = require('events').EventEmitter; -var constants = require('constants'); -var net = require('net'); -var tls = require('tls'); -var thrift = require('./thrift'); -var log = require('./log'); +var util = require("util"); +var EventEmitter = require("events").EventEmitter; +var constants = require("constants"); +var net = require("net"); +var tls = require("tls"); +var thrift = require("./thrift"); +var log = require("./log"); -var TBufferedTransport = require('./buffered_transport'); -var TBinaryProtocol = require('./binary_protocol'); -var InputBufferUnderrunError = require('./input_buffer_underrun_error'); +var TBufferedTransport = require("./buffered_transport"); +var TBinaryProtocol = require("./binary_protocol"); +var InputBufferUnderrunError = require("./input_buffer_underrun_error"); -var createClient = require('./create_client'); +var createClient = require("./create_client"); -var binary = require('./binary'); +var binary = require("./binary"); -var Connection = exports.Connection = function(stream, options) { +var Connection = (exports.Connection = function (stream, options) { var self = this; EventEmitter.call(this); this.seqId2Service = {}; this.connection = stream; - this.ssl = (stream.encrypted); + this.ssl = stream.encrypted; this.options = options || {}; this.transport = this.options.transport || TBufferedTransport; this.protocol = this.options.protocol || TBinaryProtocol; @@ -48,123 +48,139 @@ var Connection = exports.Connection = function(stream, options) { this.initialize_retry_vars(); this._debug = this.options.debug || false; - if (this.options.max_attempts && - !isNaN(this.options.max_attempts) && - this.options.max_attempts > 0) { - this.max_attempts = +this.options.max_attempts; + if ( + this.options.max_attempts && + !isNaN(this.options.max_attempts) && + this.options.max_attempts > 0 + ) { + this.max_attempts = +this.options.max_attempts; } this.retry_max_delay = null; - if (this.options.retry_max_delay !== undefined && - !isNaN(this.options.retry_max_delay) && - this.options.retry_max_delay > 0) { - this.retry_max_delay = this.options.retry_max_delay; + if ( + this.options.retry_max_delay !== undefined && + !isNaN(this.options.retry_max_delay) && + this.options.retry_max_delay > 0 + ) { + this.retry_max_delay = this.options.retry_max_delay; } this.connect_timeout = false; - if (this.options.connect_timeout && - !isNaN(this.options.connect_timeout) && - this.options.connect_timeout > 0) { - this.connect_timeout = +this.options.connect_timeout; + if ( + this.options.connect_timeout && + !isNaN(this.options.connect_timeout) && + this.options.connect_timeout > 0 + ) { + this.connect_timeout = +this.options.connect_timeout; } - this.connection.addListener(this.ssl ? "secureConnect" : "connect", function() { - self.connected = true; + this.connection.addListener( + this.ssl ? "secureConnect" : "connect", + function () { + self.connected = true; - this.setTimeout(self.options.timeout || 0); - this.setNoDelay(); - this.frameLeft = 0; - this.framePos = 0; - this.frame = null; - self.initialize_retry_vars(); - self.flush_offline_queue(); + this.setTimeout(self.options.timeout || 0); + this.setNoDelay(); + this.frameLeft = 0; + this.framePos = 0; + this.frame = null; + self.initialize_retry_vars(); + self.flush_offline_queue(); - self.emit("connect"); - }); + self.emit("connect"); + }, + ); - this.connection.addListener("error", function(err) { + this.connection.addListener("error", function (err) { // Only emit the error if no-one else is listening on the connection // or if someone is listening on us, because Node turns unhandled // 'error' events into exceptions. - if (self.connection.listeners('error').length === 1 || - self.listeners('error').length > 0) { + if ( + self.connection.listeners("error").length === 1 || + self.listeners("error").length > 0 + ) { self.emit("error", err); } }); // Add a close listener - this.connection.addListener("close", function() { + this.connection.addListener("close", function () { self.connection_gone(); // handle close event. try to reconnect }); - this.connection.addListener("timeout", function() { + this.connection.addListener("timeout", function () { self.emit("timeout"); }); - this.connection.addListener("data", self.transport.receiver(function(transport_with_data) { - var message = new self.protocol(transport_with_data); - try { - while (true) { - var header = message.readMessageBegin(); - var dummy_seqid = header.rseqid * -1; - var client = self.client; - //The Multiplexed Protocol stores a hash of seqid to service names - // in seqId2Service. If the SeqId is found in the hash we need to - // lookup the appropriate client for this call. - // The connection.client object is a single client object when not - // multiplexing, when using multiplexing it is a service name keyed - // hash of client objects. - //NOTE: The 2 way interdependencies between protocols, transports, - // connections and clients in the Node.js implementation are irregular - // and make the implementation difficult to extend and maintain. We - // should bring this stuff inline with typical thrift I/O stack - // operation soon. - // --ra - var service_name = self.seqId2Service[header.rseqid]; - if (service_name) { - client = self.client[service_name]; - } - /*jshint -W083 */ - client._reqs[dummy_seqid] = function(err, success){ - transport_with_data.commitPosition(); - - var callback = client._reqs[header.rseqid]; - delete client._reqs[header.rseqid]; + this.connection.addListener( + "data", + self.transport.receiver(function (transport_with_data) { + var message = new self.protocol(transport_with_data); + try { + while (true) { + var header = message.readMessageBegin(); + var dummy_seqid = header.rseqid * -1; + var client = self.client; + //The Multiplexed Protocol stores a hash of seqid to service names + // in seqId2Service. If the SeqId is found in the hash we need to + // lookup the appropriate client for this call. + // The connection.client object is a single client object when not + // multiplexing, when using multiplexing it is a service name keyed + // hash of client objects. + //NOTE: The 2 way interdependencies between protocols, transports, + // connections and clients in the Node.js implementation are irregular + // and make the implementation difficult to extend and maintain. We + // should bring this stuff inline with typical thrift I/O stack + // operation soon. + // --ra + var service_name = self.seqId2Service[header.rseqid]; if (service_name) { - delete self.seqId2Service[header.rseqid]; + client = self.client[service_name]; } - if (callback) { - callback(err, success); + /*jshint -W083 */ + client._reqs[dummy_seqid] = function (err, success) { + transport_with_data.commitPosition(); + + var callback = client._reqs[header.rseqid]; + delete client._reqs[header.rseqid]; + if (service_name) { + delete self.seqId2Service[header.rseqid]; + } + if (callback) { + callback(err, success); + } + }; + /*jshint +W083 */ + + if (client["recv_" + header.fname]) { + client["recv_" + header.fname](message, header.mtype, dummy_seqid); + } else { + delete client._reqs[dummy_seqid]; + self.emit( + "error", + new thrift.TApplicationException( + thrift.TApplicationExceptionType.WRONG_METHOD_NAME, + "Received a response to an unknown RPC function", + ), + ); } - }; - /*jshint +W083 */ - - if(client['recv_' + header.fname]) { - client['recv_' + header.fname](message, header.mtype, dummy_seqid); + } + } catch (e) { + if (e instanceof InputBufferUnderrunError) { + transport_with_data.rollbackPosition(); } else { - delete client._reqs[dummy_seqid]; - self.emit("error", - new thrift.TApplicationException(thrift.TApplicationExceptionType.WRONG_METHOD_NAME, - "Received a response to an unknown RPC function")); + self.emit("error", e); } } - } - catch (e) { - if (e instanceof InputBufferUnderrunError) { - transport_with_data.rollbackPosition(); - } - else { - self.emit('error', e); - } - } - })); -}; + }), + ); +}); util.inherits(Connection, EventEmitter); -Connection.prototype.end = function() { +Connection.prototype.end = function () { this.forceClose = true; this.connection.end(); }; -Connection.prototype.destroy = function() { +Connection.prototype.destroy = function () { this.connection.destroy(); }; @@ -183,12 +199,12 @@ Connection.prototype.flush_offline_queue = function () { // Reset offline queue this.offline_queue = []; // Attempt to write queued items - offline_queue.forEach(function(data) { + offline_queue.forEach(function (data) { self.write(data); }); }; -Connection.prototype.write = function(data) { +Connection.prototype.write = function (data) { if (!this.connected) { this.offline_queue.push(data); return; @@ -201,7 +217,7 @@ Connection.prototype.connection_gone = function () { this.connected = false; // If closed by manual, emit close event and cancel reconnect process - if(this.forceClose) { + if (this.forceClose) { if (this.retry_timer) { clearTimeout(this.retry_timer); this.retry_timer = null; @@ -220,7 +236,10 @@ Connection.prototype.connection_gone = function () { return; } - if (this.retry_max_delay !== null && this.retry_delay >= this.retry_max_delay) { + if ( + this.retry_max_delay !== null && + this.retry_delay >= this.retry_max_delay + ) { this.retry_delay = this.retry_max_delay; } else { this.retry_delay = Math.floor(this.retry_delay * this.retry_backoff); @@ -230,7 +249,11 @@ Connection.prototype.connection_gone = function () { if (this.max_attempts && this.attempts >= this.max_attempts) { this.retry_timer = null; - console.error("thrift: Couldn't get thrift connection after " + this.max_attempts + " attempts."); + console.error( + "thrift: Couldn't get thrift connection after " + + this.max_attempts + + " attempts.", + ); self.emit("close"); return; } @@ -238,7 +261,7 @@ Connection.prototype.connection_gone = function () { this.attempts += 1; this.emit("reconnecting", { delay: self.retry_delay, - attempt: self.attempts + attempt: self.attempts, }); this.retry_timer = setTimeout(function () { @@ -247,10 +270,14 @@ Connection.prototype.connection_gone = function () { self.retry_totaltime += self.retry_delay; if (self.connect_timeout && self.retry_totaltime >= self.connect_timeout) { - self.retry_timer = null; - console.error("thrift: Couldn't get thrift connection after " + self.retry_totaltime + "ms."); - self.emit("close"); - return; + self.retry_timer = null; + console.error( + "thrift: Couldn't get thrift connection after " + + self.retry_totaltime + + "ms.", + ); + self.emit("close"); + return; } if (self.path !== undefined) { @@ -262,11 +289,11 @@ Connection.prototype.connection_gone = function () { }, this.retry_delay); }; -exports.createConnection = function(host, port, options) { - var stream = net.createConnection( { +exports.createConnection = function (host, port, options) { + var stream = net.createConnection({ port: port, host: host, - timeout: options.connect_timeout || options.timeout || 0 + timeout: options.connect_timeout || options.timeout || 0, }); var connection = new Connection(stream, options); connection.host = host; @@ -275,7 +302,7 @@ exports.createConnection = function(host, port, options) { return connection; }; -exports.createUDSConnection = function(path, options) { +exports.createUDSConnection = function (path, options) { var stream = net.createConnection(path); var connection = new Connection(stream, options); connection.path = path; @@ -283,10 +310,11 @@ exports.createUDSConnection = function(path, options) { return connection; }; -exports.createSSLConnection = function(host, port, options) { - if (!('secureProtocol' in options) && !('secureOptions' in options)) { +exports.createSSLConnection = function (host, port, options) { + if (!("secureProtocol" in options) && !("secureOptions" in options)) { options.secureProtocol = "SSLv23_method"; - options.secureOptions = constants.SSL_OP_NO_SSLv2 | constants.SSL_OP_NO_SSLv3; + options.secureOptions = + constants.SSL_OP_NO_SSLv2 | constants.SSL_OP_NO_SSLv3; } var stream = tls.connect(port, host, options); @@ -297,15 +325,14 @@ exports.createSSLConnection = function(host, port, options) { return connection; }; - exports.createClient = createClient; -var child_process = require('child_process'); -var StdIOConnection = exports.StdIOConnection = function(command, options) { - var command_parts = command.split(' '); +var child_process = require("child_process"); +var StdIOConnection = (exports.StdIOConnection = function (command, options) { + var command_parts = command.split(" "); command = command_parts[0]; - var args = command_parts.splice(1,command_parts.length -1); - var child = this.child = child_process.spawn(command,args); + var args = command_parts.splice(1, command_parts.length - 1); + var child = (this.child = child_process.spawn(command, args)); var self = this; EventEmitter.call(this); @@ -316,13 +343,13 @@ var StdIOConnection = exports.StdIOConnection = function(command, options) { this.protocol = this.options.protocol || TBinaryProtocol; this.offline_queue = []; - if (log.getLogLevel() === 'debug') { - this.child.stderr.on('data', function (err) { - log.debug(err.toString(), 'CHILD ERROR'); + if (log.getLogLevel() === "debug") { + this.child.stderr.on("data", function (err) { + log.debug(err.toString(), "CHILD ERROR"); }); - this.child.on('exit', function (code,signal) { - log.debug(code + ':' + signal, 'CHILD EXITED'); + this.child.on("exit", function (code, signal) { + log.debug(code + ":" + signal, "CHILD EXITED"); }); } @@ -333,46 +360,47 @@ var StdIOConnection = exports.StdIOConnection = function(command, options) { self.flush_offline_queue(); - this.connection.addListener("error", function(err) { + this.connection.addListener("error", function (err) { self.emit("error", err); }); // Add a close listener - this.connection.addListener("close", function() { + this.connection.addListener("close", function () { self.emit("close"); }); - child.stdout.addListener("data", self.transport.receiver(function(transport_with_data) { - var message = new self.protocol(transport_with_data); - try { - var header = message.readMessageBegin(); - var dummy_seqid = header.rseqid * -1; - var client = self.client; - client._reqs[dummy_seqid] = function(err, success){ - transport_with_data.commitPosition(); - - var callback = client._reqs[header.rseqid]; - delete client._reqs[header.rseqid]; - if (callback) { - callback(err, success); + child.stdout.addListener( + "data", + self.transport.receiver(function (transport_with_data) { + var message = new self.protocol(transport_with_data); + try { + var header = message.readMessageBegin(); + var dummy_seqid = header.rseqid * -1; + var client = self.client; + client._reqs[dummy_seqid] = function (err, success) { + transport_with_data.commitPosition(); + + var callback = client._reqs[header.rseqid]; + delete client._reqs[header.rseqid]; + if (callback) { + callback(err, success); + } + }; + client["recv_" + header.fname](message, header.mtype, dummy_seqid); + } catch (e) { + if (e instanceof InputBufferUnderrunError) { + transport_with_data.rollbackPosition(); + } else { + throw e; } - }; - client['recv_' + header.fname](message, header.mtype, dummy_seqid); - } - catch (e) { - if (e instanceof InputBufferUnderrunError) { - transport_with_data.rollbackPosition(); - } - else { - throw e; } - } - })); -}; + }), + ); +}); util.inherits(StdIOConnection, EventEmitter); -StdIOConnection.prototype.end = function() { +StdIOConnection.prototype.end = function () { this.connection.end(); }; @@ -383,12 +411,12 @@ StdIOConnection.prototype.flush_offline_queue = function () { // Reset offline queue this.offline_queue = []; // Attempt to write queued items - offline_queue.forEach(function(data) { + offline_queue.forEach(function (data) { self.write(data); }); }; -StdIOConnection.prototype.write = function(data) { +StdIOConnection.prototype.write = function (data) { if (!this.connected) { this.offline_queue.push(data); return; @@ -396,8 +424,8 @@ StdIOConnection.prototype.write = function(data) { this.connection.write(data); }; -exports.createStdIOConnection = function(command,options){ - return new StdIOConnection(command,options); +exports.createStdIOConnection = function (command, options) { + return new StdIOConnection(command, options); }; exports.createStdIOClient = createClient; diff --git a/lib/nodejs/lib/thrift/create_client.js b/lib/nodejs/lib/thrift/create_client.js index d6b77a8339d..b9021bd4290 100644 --- a/lib/nodejs/lib/thrift/create_client.js +++ b/lib/nodejs/lib/thrift/create_client.js @@ -43,7 +43,7 @@ function createClient(ServiceClient, connection) { // - Callback to call on flush // Wrap the write method - var writeCb = function(buf, seqid) { + var writeCb = function (buf, seqid) { connection.write(buf, seqid); }; var transport = new connection.transport(undefined, writeCb); @@ -51,4 +51,4 @@ function createClient(ServiceClient, connection) { transport.client = client; connection.client = client; return client; -}; +} diff --git a/lib/nodejs/lib/thrift/framed_transport.js b/lib/nodejs/lib/thrift/framed_transport.js index 9a50a738dde..7ede2225e5f 100644 --- a/lib/nodejs/lib/thrift/framed_transport.js +++ b/lib/nodejs/lib/thrift/framed_transport.js @@ -17,9 +17,9 @@ * under the License. */ -var binary = require('./binary'); -var InputBufferUnderrunError = require('./input_buffer_underrun_error'); -var THeaderTransport = require('./header_transport'); +var binary = require("./binary"); +var InputBufferUnderrunError = require("./input_buffer_underrun_error"); +var THeaderTransport = require("./header_transport"); module.exports = TFramedTransport; @@ -30,68 +30,65 @@ function TFramedTransport(buffer, callback) { this.outCount = 0; this.readPos = 0; this.onFlush = callback; -}; +} Object.setPrototypeOf(TFramedTransport.prototype, THeaderTransport.prototype); -TFramedTransport.receiver = function(callback, seqid) { - var residual = []; +TFramedTransport.receiver = function (callback, seqid) { + var residual = new Buffer(0); - return function(data) { - // push received data to residual - for(var i = 0; i < data.length; ++i) { - residual.push(data[i]) - } + return function (data) { + residual = Buffer.concat([residual, Buffer.from(data)]); while (residual.length > 0) { if (residual.length < 4) { // Not enough bytes to continue, save and resume on next packet return; } - // get single package sieze - var frameSize = binary.readI32(Buffer.from(residual.slice(0, 4)), 0); + // Get single package size + var frameSize = binary.readI32(residual, 0); // Not enough bytes to continue, save and resume on next packet if (residual.length < 4 + frameSize) { return; } - // splice first 4 bytes - residual.splice(0, 4) - // get package data - var frame = Buffer.from(residual.splice(0, frameSize)); + // Get package data + var frame = residual.subarray(4, 4 + frameSize); + // Remove processed data from residual + residual = residual.subarray(4 + frameSize); callback(new TFramedTransport(frame), seqid); } }; }; -TFramedTransport.prototype.commitPosition = function(){}, -TFramedTransport.prototype.rollbackPosition = function(){}, - +(TFramedTransport.prototype.commitPosition = function () {}), + (TFramedTransport.prototype.rollbackPosition = function () {}), // TODO: Implement open/close support -TFramedTransport.prototype.isOpen = function() { - return true; -}; -TFramedTransport.prototype.open = function() {}; -TFramedTransport.prototype.close = function() {}; + (TFramedTransport.prototype.isOpen = function () { + return true; + }); +TFramedTransport.prototype.open = function () {}; +TFramedTransport.prototype.close = function () {}; - // Set the seqid of the message in the client - // So that callbacks can be found -TFramedTransport.prototype.setCurrSeqId = function(seqid) { +// Set the seqid of the message in the client +// So that callbacks can be found +TFramedTransport.prototype.setCurrSeqId = function (seqid) { this._seqid = seqid; }; -TFramedTransport.prototype.ensureAvailable = function(len) { +TFramedTransport.prototype.ensureAvailable = function (len) { if (this.readPos + len > this.inBuf.length) { throw new InputBufferUnderrunError(); } }; -TFramedTransport.prototype.read = function(len) { // this function will be used for each frames. +TFramedTransport.prototype.read = function (len) { + // this function will be used for each frames. this.ensureAvailable(len); var end = this.readPos + len; if (this.inBuf.length < end) { - throw new Error('read(' + len + ') failed - not enough data'); + throw new Error("read(" + len + ") failed - not enough data"); } var buf = this.inBuf.slice(this.readPos, end); @@ -99,68 +96,68 @@ TFramedTransport.prototype.read = function(len) { // this function will be used return buf; }; -TFramedTransport.prototype.readByte = function() { +TFramedTransport.prototype.readByte = function () { this.ensureAvailable(1); return binary.readByte(this.inBuf[this.readPos++]); }; -TFramedTransport.prototype.readI16 = function() { +TFramedTransport.prototype.readI16 = function () { this.ensureAvailable(2); var i16 = binary.readI16(this.inBuf, this.readPos); this.readPos += 2; return i16; }; -TFramedTransport.prototype.readI32 = function() { +TFramedTransport.prototype.readI32 = function () { this.ensureAvailable(4); var i32 = binary.readI32(this.inBuf, this.readPos); this.readPos += 4; return i32; }; -TFramedTransport.prototype.readDouble = function() { +TFramedTransport.prototype.readDouble = function () { this.ensureAvailable(8); var d = binary.readDouble(this.inBuf, this.readPos); this.readPos += 8; return d; }; -TFramedTransport.prototype.readString = function(len) { +TFramedTransport.prototype.readString = function (len) { this.ensureAvailable(len); - var str = this.inBuf.toString('utf8', this.readPos, this.readPos + len); + var str = this.inBuf.toString("utf8", this.readPos, this.readPos + len); this.readPos += len; return str; }; -TFramedTransport.prototype.borrow = function() { +TFramedTransport.prototype.borrow = function () { return { buf: this.inBuf, readIndex: this.readPos, - writeIndex: this.inBuf.length + writeIndex: this.inBuf.length, }; }; -TFramedTransport.prototype.consume = function(bytesConsumed) { +TFramedTransport.prototype.consume = function (bytesConsumed) { this.readPos += bytesConsumed; }; -TFramedTransport.prototype.write = function(buf, encoding) { - if (typeof(buf) === "string") { - buf = new Buffer(buf, encoding || 'utf8'); +TFramedTransport.prototype.write = function (buf, encoding) { + if (typeof buf === "string") { + buf = new Buffer(buf, encoding || "utf8"); } this.outBuffers.push(buf); this.outCount += buf.length; }; -TFramedTransport.prototype.flush = function() { +TFramedTransport.prototype.flush = function () { // If the seqid of the callback is available pass it to the onFlush // Then remove the current seqid var seqid = this._seqid; this._seqid = null; var out = new Buffer(this.outCount), - pos = 0; - this.outBuffers.forEach(function(buf) { + pos = 0; + this.outBuffers.forEach(function (buf) { buf.copy(out, pos, 0); pos += buf.length; }); diff --git a/lib/nodejs/lib/thrift/header_protocol.js b/lib/nodejs/lib/thrift/header_protocol.js index 8971751fb75..2a48a4d7d2a 100644 --- a/lib/nodejs/lib/thrift/header_protocol.js +++ b/lib/nodejs/lib/thrift/header_protocol.js @@ -16,10 +16,10 @@ * 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 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; @@ -54,204 +54,206 @@ util.inherits(THeaderProtocolError, Error); function THeaderProtocol(trans) { if (!(trans instanceof THeaderTransport)) { throw new THeaderProtocolError( - 'Only transports that inherit THeaderTransport can be' + - ' used with THeaderProtocol' + "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 +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) { +THeaderProtocol.prototype.writeMessageBegin = function (name, type, seqid) { return this.protocol.writeMessageBegin(name, type, seqid); }; -THeaderProtocol.prototype.writeMessageEnd = function() { +THeaderProtocol.prototype.writeMessageEnd = function () { return this.protocol.writeMessageEnd(); }; -THeaderProtocol.prototype.writeStructBegin = function(name) { +THeaderProtocol.prototype.writeStructBegin = function (name) { return this.protocol.writeStructBegin(name); }; -THeaderProtocol.prototype.writeStructEnd = function() { +THeaderProtocol.prototype.writeStructEnd = function () { return this.protocol.writeStructEnd(); }; -THeaderProtocol.prototype.writeFieldBegin = function(name, type, id) { +THeaderProtocol.prototype.writeFieldBegin = function (name, type, id) { return this.protocol.writeFieldBegin(name, type, id); -} +}; -THeaderProtocol.prototype.writeFieldEnd = function() { +THeaderProtocol.prototype.writeFieldEnd = function () { return this.protocol.writeFieldEnd(); }; -THeaderProtocol.prototype.writeFieldStop = function() { +THeaderProtocol.prototype.writeFieldStop = function () { return this.protocol.writeFieldStop(); }; -THeaderProtocol.prototype.writeMapBegin = function(ktype, vtype, size) { +THeaderProtocol.prototype.writeMapBegin = function (ktype, vtype, size) { return this.protocol.writeMapBegin(ktype, vtype, size); }; -THeaderProtocol.prototype.writeMapEnd = function() { +THeaderProtocol.prototype.writeMapEnd = function () { return this.protocol.writeMapEnd(); }; -THeaderProtocol.prototype.writeListBegin = function(etype, size) { +THeaderProtocol.prototype.writeListBegin = function (etype, size) { return this.protocol.writeListBegin(etype, size); }; -THeaderProtocol.prototype.writeListEnd = function() { +THeaderProtocol.prototype.writeListEnd = function () { return this.protocol.writeListEnd(); }; -THeaderProtocol.prototype.writeSetBegin = function(etype, size) { +THeaderProtocol.prototype.writeSetBegin = function (etype, size) { return this.protocol.writeSetBegin(etype, size); }; -THeaderProtocol.prototype.writeSetEnd = function() { +THeaderProtocol.prototype.writeSetEnd = function () { return this.protocol.writeSetEnd(); }; -THeaderProtocol.prototype.writeBool = function(b) { +THeaderProtocol.prototype.writeBool = function (b) { return this.protocol.writeBool(b); }; -THeaderProtocol.prototype.writeByte = function(b) { +THeaderProtocol.prototype.writeByte = function (b) { return this.protocol.writeByte(b); }; -THeaderProtocol.prototype.writeI16 = function(i16) { +THeaderProtocol.prototype.writeI16 = function (i16) { return this.protocol.writeI16(i16); }; -THeaderProtocol.prototype.writeI32 = function(i32) { +THeaderProtocol.prototype.writeI32 = function (i32) { return this.protocol.writeI32(i32); }; -THeaderProtocol.prototype.writeI64 = function(i64) { +THeaderProtocol.prototype.writeI64 = function (i64) { return this.protocol.writeI64(i64); }; -THeaderProtocol.prototype.writeDouble = function(dub) { +THeaderProtocol.prototype.writeDouble = function (dub) { return this.protocol.writeDouble(dub); }; -THeaderProtocol.prototype.writeStringOrBinary = function(name, encoding, arg) { +THeaderProtocol.prototype.writeStringOrBinary = function (name, encoding, arg) { return this.protocol.writeStringOrBinary(name, encoding, arg); }; -THeaderProtocol.prototype.writeString = function(arg) { +THeaderProtocol.prototype.writeString = function (arg) { return this.protocol.writeString(arg); }; -THeaderProtocol.prototype.writeBinary = function(arg) { +THeaderProtocol.prototype.writeBinary = function (arg) { return this.protocol.writeBinary(arg); }; -THeaderProtocol.prototype.readMessageBegin = function() { +THeaderProtocol.prototype.readMessageBegin = function () { this.trans.readHeaders(); this.setProtocol(); return this.protocol.readMessageBegin(); }; -THeaderProtocol.prototype.readMessageEnd = function() { +THeaderProtocol.prototype.readMessageEnd = function () { return this.protocol.readMessageEnd(); }; -THeaderProtocol.prototype.readStructBegin = function() { +THeaderProtocol.prototype.readStructBegin = function () { return this.protocol.readStructBegin(); }; -THeaderProtocol.prototype.readStructEnd = function() { +THeaderProtocol.prototype.readStructEnd = function () { return this.protocol.readStructEnd(); }; -THeaderProtocol.prototype.readFieldBegin = function() { +THeaderProtocol.prototype.readFieldBegin = function () { return this.protocol.readFieldBegin(); }; -THeaderProtocol.prototype.readFieldEnd = function() { +THeaderProtocol.prototype.readFieldEnd = function () { return this.protocol.readFieldEnd(); }; -THeaderProtocol.prototype.readMapBegin = function() { +THeaderProtocol.prototype.readMapBegin = function () { return this.protocol.readMapBegin(); }; -THeaderProtocol.prototype.readMapEnd = function() { +THeaderProtocol.prototype.readMapEnd = function () { return this.protocol.readMapEnd(); }; -THeaderProtocol.prototype.readListBegin = function() { +THeaderProtocol.prototype.readListBegin = function () { return this.protocol.readListBegin(); }; -THeaderProtocol.prototype.readListEnd = function() { +THeaderProtocol.prototype.readListEnd = function () { return this.protocol.readListEnd(); }; -THeaderProtocol.prototype.readSetBegin = function() { +THeaderProtocol.prototype.readSetBegin = function () { return this.protocol.readSetBegin(); }; -THeaderProtocol.prototype.readSetEnd = function() { +THeaderProtocol.prototype.readSetEnd = function () { return this.protocol.readSetEnd(); }; -THeaderProtocol.prototype.readBool = function() { +THeaderProtocol.prototype.readBool = function () { return this.protocol.readBool(); }; -THeaderProtocol.prototype.readByte = function() { +THeaderProtocol.prototype.readByte = function () { return this.protocol.readByte(); }; -THeaderProtocol.prototype.readI16 = function() { +THeaderProtocol.prototype.readI16 = function () { return this.protocol.readI16(); }; -THeaderProtocol.prototype.readI32 = function() { +THeaderProtocol.prototype.readI32 = function () { return this.protocol.readI32(); }; -THeaderProtocol.prototype.readI64 = function() { +THeaderProtocol.prototype.readI64 = function () { return this.protocol.readI64(); }; -THeaderProtocol.prototype.readDouble = function() { +THeaderProtocol.prototype.readDouble = function () { return this.protocol.readDouble(); }; -THeaderProtocol.prototype.readBinary = function() { +THeaderProtocol.prototype.readBinary = function () { return this.protocol.readBinary(); }; -THeaderProtocol.prototype.readString = function() { +THeaderProtocol.prototype.readString = function () { return this.protocol.readString(); }; -THeaderProtocol.prototype.getTransport = function() { +THeaderProtocol.prototype.getTransport = function () { return this.trans; }; -THeaderProtocol.prototype.skip = function(type) { +THeaderProtocol.prototype.skip = function (type) { return this.protocol.skip(type); }; -THeaderProtocol.prototype.setProtocol = function(subProtocolId) { +THeaderProtocol.prototype.setProtocol = function (subProtocolId) { var subProtocolId = this.trans.getProtocolId(); if (!ProtocolMap[subProtocolId]) { - throw new THeaderProtocolError('Headers not supported for protocol ' + 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 index ec8624b02a7..37da4924129 100644 --- a/lib/nodejs/lib/thrift/header_transport.js +++ b/lib/nodejs/lib/thrift/header_transport.js @@ -17,10 +17,10 @@ * under the License. */ -var util = require('util'); -var TCompactProtocol = require('./compact_protocol'); -var TBinaryProtocol = require('./binary_protocol'); -var InputBufferUnderrunError = require('./input_buffer_underrun_error'); +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); @@ -45,51 +45,51 @@ var SEQID_OFFSET = 64 / 8; var HEADER_SIZE_OFFSET = 96 / 8; var HEADER_START_OFFSET = 112 / 8; -var HEADER_MAGIC = 0x0FFF; +var HEADER_MAGIC = 0x0fff; var TINFO_HEADER_KEY_VALUE_TYPE = 0x01; -var MAX_FRAME_SIZE = 0x3FFFFFFF; +var MAX_FRAME_SIZE = 0x3fffffff; - // A helper class for reading/writing varints. Uses - // TCompactProtocol under the hood +// A helper class for reading/writing varints. Uses +// TCompactProtocol under the hood function VarintHelper(readBuffer) { - var TBufferedTransport = require('./buffered_transport'); + var TBufferedTransport = require("./buffered_transport"); this.outputBuffer = null; var _this = this; - this.transport = new TBufferedTransport(null, function(output) { + 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() { +VarintHelper.prototype.readVarint32 = function () { return this.protocol.readVarint32(); }; -VarintHelper.prototype.writeVarint32 = function(i) { +VarintHelper.prototype.writeVarint32 = function (i) { this.protocol.writeVarint32(i); }; -VarintHelper.prototype.readString = function() { +VarintHelper.prototype.readString = function () { return this.protocol.readString(); }; -VarintHelper.prototype.writeString = function(str) { +VarintHelper.prototype.writeString = function (str) { this.protocol.writeString(str); -} +}; -VarintHelper.prototype.getOutCount = function() { +VarintHelper.prototype.getOutCount = function () { return this.transport.outCount; }; -VarintHelper.prototype.write = function(str) { +VarintHelper.prototype.write = function (str) { this.transport.write(str); }; -VarintHelper.prototype.toBuffer = function() { +VarintHelper.prototype.toBuffer = function () { this.transport.flush(); return this.outputBuffer; }; @@ -127,87 +127,90 @@ function THeaderTransport() { 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 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 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; + if (protocolId === THeaderTransport.SubprotocolId[protocols[i]]) + return true; } - throw new Error(protocolId + ' is not a valid protocol id'); + throw new Error(protocolId + " is not a valid protocol id"); }; -THeaderTransport.prototype.setSeqId = function(seqid) { +THeaderTransport.prototype.setSeqId = function (seqid) { this.seqid = seqid; }; -THeaderTransport.prototype.getSeqId = function(seqid) { +THeaderTransport.prototype.getSeqId = function (seqid) { return this.seqid; }; -THeaderTransport.prototype.setFlags = function(flags) { +THeaderTransport.prototype.setFlags = function (flags) { this.flags = flags; }; -THeaderTransport.prototype.getReadHeaders = function() { +THeaderTransport.prototype.getReadHeaders = function () { return this.rheaders; }; -THeaderTransport.prototype.setReadHeader = function(key, value) { +THeaderTransport.prototype.setReadHeader = function (key, value) { validateHeaders(key, value); this.rheaders[key] = value; }; -THeaderTransport.prototype.clearReadHeaders = function() { +THeaderTransport.prototype.clearReadHeaders = function () { this.rheaders = {}; }; -THeaderTransport.prototype.getWriteHeaders = function() { +THeaderTransport.prototype.getWriteHeaders = function () { return this.wheaders; }; -THeaderTransport.prototype.setWriteHeader = function(key, value) { +THeaderTransport.prototype.setWriteHeader = function (key, value) { validateHeaders(key, value); this.wheaders[key] = value; }; -THeaderTransport.prototype.clearWriteHeaders = function() { +THeaderTransport.prototype.clearWriteHeaders = function () { this.wheaders = {}; }; -THeaderTransport.prototype.setMaxFrameSize = function(frameSize) { +THeaderTransport.prototype.setMaxFrameSize = function (frameSize) { this.maxFrameSize = frameSize; }; -THeaderTransport.prototype.setProtocolId = function(protocolId) { +THeaderTransport.prototype.setProtocolId = function (protocolId) { validateProtocolId(protocolId); this.protocolId = protocolId; }; -THeaderTransport.prototype.getProtocolId = function() { +THeaderTransport.prototype.getProtocolId = function () { return this.protocolId; }; -var isUnframedBinary = function(readBuffer) { +var isUnframedBinary = function (readBuffer) { var version = readBuffer.readInt32BE(); return (version & TBinaryProtocol.VERSION_MASK) === TBinaryProtocol.VERSION_1; -} +}; -var isUnframedCompact = function(readBuffer) { +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; -} + return ( + protocolId === TCompactProtocol.PROTOCOL_ID && + (version & TCompactProtocol.VERSION_MASK) === TCompactProtocol.VERSION_N + ); +}; -THeaderTransport.prototype.readHeaders = function() { +THeaderTransport.prototype.readHeaders = function () { var readBuffer = this.inBuf; var isUnframed = false; @@ -228,7 +231,7 @@ THeaderTransport.prototype.readHeaders = function() { var frameSize = readBuffer.readInt32BE(FRAME_SIZE_OFFSET); if (frameSize > this.maxFrameSize) { - throw new THeaderTransportError('Frame exceeds maximum frame size'); + throw new THeaderTransportError("Frame exceeds maximum frame size"); } var headerMagic = readBuffer.readInt16BE(HEADER_MAGIC_OFFSET); @@ -242,7 +245,7 @@ THeaderTransport.prototype.readHeaders = function() { 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'); + throw new THeaderTransportError("Header size is greater than frame size"); } var headerBuffer = Buffer.alloc(headerSize); @@ -252,7 +255,7 @@ THeaderTransport.prototype.readHeaders = function() { this.setProtocolId(varintHelper.readVarint32()); var transformCount = varintHelper.readVarint32(); if (transformCount > 0) { - throw new THeaderTransportError('Transforms are not yet supported'); + throw new THeaderTransportError("Transforms are not yet supported"); } while (true) { @@ -281,7 +284,7 @@ THeaderTransport.prototype.readHeaders = function() { return this.getReadHeaders(); }; -THeaderTransport.prototype.writeHeaders = function() { +THeaderTransport.prototype.writeHeaders = function () { // only write headers on the server if the client contained headers if (!this.shouldWriteHeaders) { return; @@ -305,11 +308,13 @@ THeaderTransport.prototype.writeHeaders = function() { varintWriter.writeString(value); } } - var headerSizeWithoutPadding = varintWriter.getOutCount(); + var headerSizeWithoutPadding = varintWriter.getOutCount(); var paddingNeeded = (4 - (headerSizeWithoutPadding % 4)) % 4; var headerSize = Buffer.alloc(2); - headerSize.writeInt16BE(Math.floor((headerSizeWithoutPadding + paddingNeeded) / 4)); + headerSize.writeInt16BE( + Math.floor((headerSizeWithoutPadding + paddingNeeded) / 4), + ); var paddingBuffer = Buffer.alloc(paddingNeeded); paddingBuffer.fill(0x00); diff --git a/lib/nodejs/lib/thrift/http_connection.js b/lib/nodejs/lib/thrift/http_connection.js index 17e0d0c2995..50d3312baad 100644 --- a/lib/nodejs/lib/thrift/http_connection.js +++ b/lib/nodejs/lib/thrift/http_connection.js @@ -16,17 +16,17 @@ * specific language governing permissions and limitations * under the License. */ -var util = require('util'); -var http = require('http'); -var https = require('https'); -var EventEmitter = require('events').EventEmitter; -var thrift = require('./thrift'); +var util = require("util"); +var http = require("http"); +var https = require("https"); +var EventEmitter = require("events").EventEmitter; +var thrift = require("./thrift"); -var TBufferedTransport = require('./buffered_transport'); -var TBinaryProtocol = require('./binary_protocol'); -var InputBufferUnderrunError = require('./input_buffer_underrun_error'); +var TBufferedTransport = require("./buffered_transport"); +var TBinaryProtocol = require("./binary_protocol"); +var InputBufferUnderrunError = require("./input_buffer_underrun_error"); -var createClient = require('./create_client'); +var createClient = require("./create_client"); /** * @class @@ -69,7 +69,7 @@ var createClient = require('./create_client'); * semantics implemented over the Node.js http.request() method. * @see {@link createHttpConnection} */ -var HttpConnection = exports.HttpConnection = function(options) { +var HttpConnection = (exports.HttpConnection = function (options) { //Initialize the emitter base object EventEmitter.call(this); @@ -88,17 +88,17 @@ var HttpConnection = exports.HttpConnection = function(options) { host: this.host, port: this.port, socketPath: this.socketPath, - path: this.options.path || '/', - method: 'POST', + path: this.options.path || "/", + method: "POST", headers: this.options.headers || {}, - responseType: this.options.responseType || null + responseType: this.options.responseType || null, }; for (var attrname in this.options.nodeOptions) { this.nodeOptions[attrname] = this.options.nodeOptions[attrname]; } /*jshint -W069 */ - if (! this.nodeOptions.headers['Connection']) { - this.nodeOptions.headers['Connection'] = 'keep-alive'; + if (!this.nodeOptions.headers["Connection"]) { + this.nodeOptions.headers["Connection"] = "keep-alive"; } /*jshint +W069 */ @@ -131,41 +131,42 @@ var HttpConnection = exports.HttpConnection = function(options) { delete self.seqId2Service[header.rseqid]; } /*jshint -W083 */ - client._reqs[dummy_seqid] = function(err, success){ + client._reqs[dummy_seqid] = function (err, success) { transport_with_data.commitPosition(); var clientCallback = client._reqs[header.rseqid]; delete client._reqs[header.rseqid]; if (clientCallback) { - process.nextTick(function() { + process.nextTick(function () { clientCallback(err, success); }); } }; /*jshint +W083 */ - if(client['recv_' + header.fname]) { - client['recv_' + header.fname](proto, header.mtype, dummy_seqid); + if (client["recv_" + header.fname]) { + client["recv_" + header.fname](proto, header.mtype, dummy_seqid); } else { delete client._reqs[dummy_seqid]; - self.emit("error", - new thrift.TApplicationException( - thrift.TApplicationExceptionType.WRONG_METHOD_NAME, - "Received a response to an unknown RPC function")); + self.emit( + "error", + new thrift.TApplicationException( + thrift.TApplicationExceptionType.WRONG_METHOD_NAME, + "Received a response to an unknown RPC function", + ), + ); } } - } - catch (e) { + } catch (e) { if (e instanceof InputBufferUnderrunError) { transport_with_data.rollbackPosition(); } else { - self.emit('error', e); + self.emit("error", e); } } } - //Response handler ////////////////////////////////////////////////// - this.responseCallback = function(response) { + this.responseCallback = function (response) { var data = []; var dataLen = 0; @@ -173,16 +174,18 @@ var HttpConnection = exports.HttpConnection = function(options) { this.emit("error", new THTTPException(response)); } - response.on('error', function (e) { + response.on("error", function (e) { self.emit("error", e); }); // When running directly under node, chunk will be a buffer, // however, when running in a Browser (e.g. Browserify), chunk // will be a string or an ArrayBuffer. - response.on('data', function (chunk) { - if ((typeof chunk == 'string') || - (Object.prototype.toString.call(chunk) == '[object Uint8Array]')) { + response.on("data", function (chunk) { + if ( + typeof chunk == "string" || + Object.prototype.toString.call(chunk) == "[object Uint8Array]" + ) { // Wrap ArrayBuffer/string in a Buffer so data[i].copy will work data.push(new Buffer(chunk)); } else { @@ -191,9 +194,9 @@ var HttpConnection = exports.HttpConnection = function(options) { dataLen += chunk.length; }); - response.on('end', function(){ + response.on("end", function () { var buf = new Buffer(dataLen); - for (var i=0, len=data.length, pos=0; i (negative ? 20 : 19)) { - throw new RangeError('Too many digits for Int64: ' + text); + throw new RangeError("Too many digits for Int64: " + text); } else { // Most significant (up to 5) digits var high5 = +text.slice(negative ? 1 : 0, -15); - var low = +text.slice(-15) + high5 * 2764472320; // The literal is 10^15 % 2^32 - var high = Math.floor(low / POW2_32) + high5 * 232830; // The literal is 10^15 / 2^&32 + var low = +text.slice(-15) + high5 * 2764472320; // The literal is 10^15 % 2^32 + var high = Math.floor(low / POW2_32) + high5 * 232830; // The literal is 10^15 / 2^&32 low = low % POW2_32; - if (high >= POW2_31 && - !(negative && high == POW2_31 && low == 0) // Allow minimum Int64 - ) { - throw new RangeError('The magnitude is too large for Int64.'); + if ( + high >= POW2_31 && + !(negative && high == POW2_31 && low == 0) // Allow minimum Int64 + ) { + throw new RangeError("The magnitude is too large for Int64."); } if (negative) { // 2's complement diff --git a/lib/nodejs/lib/thrift/json_parse.js b/lib/nodejs/lib/thrift/json_parse.js index 93b0bf2ab95..3d111c08e53 100644 --- a/lib/nodejs/lib/thrift/json_parse.js +++ b/lib/nodejs/lib/thrift/json_parse.js @@ -12,7 +12,6 @@ * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. */ - /*jslint for */ /*property @@ -20,280 +19,260 @@ prototype, push, r, t, text */ -var Int64 = require('node-int64'); -var Int64Util = require('./int64_util'); - -var json_parse = module.exports = (function () { - "use strict"; - -// This is a function that can parse a JSON text, producing a JavaScript -// data structure. It is a simple, recursive descent parser. It does not use -// eval or regular expressions, so it can be used as a model for implementing -// a JSON parser in other languages. - -// We are defining the function inside of another function to avoid creating -// global variables. - - var at, // The index of the current character - ch, // The current character - escapee = { - '"': '"', - '\\': '\\', - '/': '/', - b: '\b', - f: '\f', - n: '\n', - r: '\r', - t: '\t' - }, - text, - - error = function (m) { - -// Call error when something is wrong. - - throw new SyntaxError(m); - }, - - next = function (c) { - -// If a c parameter is provided, verify that it matches the current character. - - if (c && c !== ch) { - error("Expected '" + c + "' instead of '" + ch + "'"); - } - -// Get the next character. When there are no more characters, -// return the empty string. - - ch = text.charAt(at); - at += 1; - return ch; - }, - - number = function () { - -// Parse a number value. - - var number, - string = ''; - - if (ch === '-') { - string = '-'; - next('-'); - } - while (ch >= '0' && ch <= '9') { - string += ch; - next(); - } - if (ch === '.') { - string += '.'; - while (next() && ch >= '0' && ch <= '9') { - string += ch; - } - } - if (ch === 'e' || ch === 'E') { - string += ch; - next(); - if (ch === '-' || ch === '+') { - string += ch; - next(); - } - while (ch >= '0' && ch <= '9') { - string += ch; - next(); +var Int64 = require("node-int64"); +var Int64Util = require("./int64_util"); + +var json_parse = (module.exports = (function () { + "use strict"; + + // This is a function that can parse a JSON text, producing a JavaScript + // data structure. It is a simple, recursive descent parser. It does not use + // eval or regular expressions, so it can be used as a model for implementing + // a JSON parser in other languages. + + // We are defining the function inside of another function to avoid creating + // global variables. + + var at, // The index of the current character + ch, // The current character + escapee = { + '"': '"', + "\\": "\\", + "/": "/", + b: "\b", + f: "\f", + n: "\n", + r: "\r", + t: "\t", + }, + text, + error = function (m) { + // Call error when something is wrong. + + throw new SyntaxError(m); + }, + next = function (c) { + // If a c parameter is provided, verify that it matches the current character. + + if (c && c !== ch) { + error("Expected '" + c + "' instead of '" + ch + "'"); + } + + // Get the next character. When there are no more characters, + // return the empty string. + + ch = text.charAt(at); + at += 1; + return ch; + }, + number = function () { + // Parse a number value. + + var number, + string = ""; + + if (ch === "-") { + string = "-"; + next("-"); + } + while (ch >= "0" && ch <= "9") { + string += ch; + next(); + } + if (ch === ".") { + string += "."; + while (next() && ch >= "0" && ch <= "9") { + string += ch; + } + } + if (ch === "e" || ch === "E") { + string += ch; + next(); + if (ch === "-" || ch === "+") { + string += ch; + next(); + } + while (ch >= "0" && ch <= "9") { + string += ch; + next(); + } + } + number = +string; + if (!isFinite(number)) { + error("Bad number"); + } else if (number >= Int64.MAX_INT || number <= Int64.MIN_INT) { + // Return raw string for further process in TJSONProtocol + return string; + } else { + return number; + } + }, + string = function () { + // Parse a string value. + + var hex, + i, + string = "", + uffff; + + // When parsing for string values, we must look for " and \ characters. + + if (ch === '"') { + while (next()) { + if (ch === '"') { + next(); + return string; + } + if (ch === "\\") { + next(); + if (ch === "u") { + uffff = 0; + for (i = 0; i < 4; i += 1) { + hex = parseInt(next(), 16); + if (!isFinite(hex)) { + break; } - } - number = +string; - if (!isFinite(number)) { - error("Bad number"); - } else if (number >= Int64.MAX_INT || number <= Int64.MIN_INT) { - // Return raw string for further process in TJSONProtocol - return string; + uffff = uffff * 16 + hex; + } + string += String.fromCharCode(uffff); + } else if (typeof escapee[ch] === "string") { + string += escapee[ch]; } else { - return number; - } - }, - - string = function () { - -// Parse a string value. - - var hex, - i, - string = '', - uffff; - -// When parsing for string values, we must look for " and \ characters. - - if (ch === '"') { - while (next()) { - if (ch === '"') { - next(); - return string; - } - if (ch === '\\') { - next(); - if (ch === 'u') { - uffff = 0; - for (i = 0; i < 4; i += 1) { - hex = parseInt(next(), 16); - if (!isFinite(hex)) { - break; - } - uffff = uffff * 16 + hex; - } - string += String.fromCharCode(uffff); - } else if (typeof escapee[ch] === 'string') { - string += escapee[ch]; - } else { - break; - } - } else { - string += ch; - } - } + break; } - error("Bad string"); - }, - - white = function () { - -// Skip whitespace. - - while (ch && ch <= ' ') { - next(); - } - }, - - word = function () { - -// true, false, or null. - - switch (ch) { - case 't': - next('t'); - next('r'); - next('u'); - next('e'); - return true; - case 'f': - next('f'); - next('a'); - next('l'); - next('s'); - next('e'); - return false; - case 'n': - next('n'); - next('u'); - next('l'); - next('l'); - return null; - } - error("Unexpected '" + ch + "'"); - }, - - value, // Place holder for the value function. - - array = function () { - -// Parse an array value. - - var array = []; - - if (ch === '[') { - next('['); - white(); - if (ch === ']') { - next(']'); - return array; // empty array - } - while (ch) { - array.push(value()); - white(); - if (ch === ']') { - next(']'); - return array; - } - next(','); - white(); - } - } - error("Bad array"); - }, - - object = function () { - -// Parse an object value. - - var key, - object = {}; - - if (ch === '{') { - next('{'); - white(); - if (ch === '}') { - next('}'); - return object; // empty object - } - while (ch) { - key = string(); - white(); - next(':'); - if (Object.hasOwnProperty.call(object, key)) { - error('Duplicate key "' + key + '"'); - } - object[key] = value(); - white(); - if (ch === '}') { - next('}'); - return object; - } - next(','); - white(); - } - } - error("Bad object"); - }; - - value = function () { - -// Parse a JSON value. It could be an object, an array, a string, a number, -// or a word. - + } else { + string += ch; + } + } + } + error("Bad string"); + }, + white = function () { + // Skip whitespace. + + while (ch && ch <= " ") { + next(); + } + }, + word = function () { + // true, false, or null. + + switch (ch) { + case "t": + next("t"); + next("r"); + next("u"); + next("e"); + return true; + case "f": + next("f"); + next("a"); + next("l"); + next("s"); + next("e"); + return false; + case "n": + next("n"); + next("u"); + next("l"); + next("l"); + return null; + } + error("Unexpected '" + ch + "'"); + }, + value, // Place holder for the value function. + array = function () { + // Parse an array value. + + var array = []; + + if (ch === "[") { + next("["); white(); - switch (ch) { - case '{': - return object(); - case '[': - return array(); - case '"': - return string(); - case '-': - return number(); - default: - return ch >= '0' && ch <= '9' - ? number() - : word(); + if (ch === "]") { + next("]"); + return array; // empty array } - }; - -// Return the json_parse function. It will have access to all of the above -// functions and variables. + while (ch) { + array.push(value()); + white(); + if (ch === "]") { + next("]"); + return array; + } + next(","); + white(); + } + } + error("Bad array"); + }, + object = function () { + // Parse an object value. - return function (source) { - var result; + var key, + object = {}; - text = source; - at = 0; - ch = ' '; - result = value(); + if (ch === "{") { + next("{"); white(); - if (ch) { - error("Syntax error"); + if (ch === "}") { + next("}"); + return object; // empty object } - - return result; + while (ch) { + key = string(); + white(); + next(":"); + if (Object.hasOwnProperty.call(object, key)) { + error('Duplicate key "' + key + '"'); + } + object[key] = value(); + white(); + if (ch === "}") { + next("}"); + return object; + } + next(","); + white(); + } + } + error("Bad object"); }; -}()); + + value = function () { + // Parse a JSON value. It could be an object, an array, a string, a number, + // or a word. + + white(); + switch (ch) { + case "{": + return object(); + case "[": + return array(); + case '"': + return string(); + case "-": + return number(); + default: + return ch >= "0" && ch <= "9" ? number() : word(); + } + }; + + // Return the json_parse function. It will have access to all of the above + // functions and variables. + + return function (source) { + var result; + + text = source; + at = 0; + ch = " "; + result = value(); + white(); + if (ch) { + error("Syntax error"); + } + + return result; + }; +})()); diff --git a/lib/nodejs/lib/thrift/json_protocol.js b/lib/nodejs/lib/thrift/json_protocol.js index 7e2b7c90891..31dcb8196a7 100644 --- a/lib/nodejs/lib/thrift/json_protocol.js +++ b/lib/nodejs/lib/thrift/json_protocol.js @@ -17,15 +17,15 @@ * under the License. */ -var Int64 = require('node-int64'); -var Thrift = require('./thrift'); +var Int64 = require("node-int64"); +var Thrift = require("./thrift"); var Type = Thrift.Type; var util = require("util"); -var Int64Util = require('./int64_util'); -var json_parse = require('./json_parse'); +var Int64Util = require("./int64_util"); +var json_parse = require("./json_parse"); -var InputBufferUnderrunError = require('./input_buffer_underrun_error'); +var InputBufferUnderrunError = require("./input_buffer_underrun_error"); module.exports = TJSONProtocol; @@ -43,7 +43,7 @@ function TJSONProtocol(trans) { this.tstack = []; this.tpos = []; this.trans = trans; -}; +} /** * Thrift IDL type Id to string mapping. @@ -89,12 +89,12 @@ TJSONProtocol.RType.set = Type.SET; */ TJSONProtocol.Version = 1; -TJSONProtocol.prototype.flush = function() { +TJSONProtocol.prototype.flush = function () { this.writeToTransportIfStackIsFlushable(); return this.trans.flush(); }; -TJSONProtocol.prototype.writeToTransportIfStackIsFlushable = function() { +TJSONProtocol.prototype.writeToTransportIfStackIsFlushable = function () { if (this.tstack.length === 1) { this.trans.write(this.tstack.pop()); } @@ -106,20 +106,29 @@ TJSONProtocol.prototype.writeToTransportIfStackIsFlushable = function() { * @param {Thrift.MessageType} messageType - The type of method call. * @param {number} seqid - The sequence number of this call (always 0 in Apache Thrift). */ -TJSONProtocol.prototype.writeMessageBegin = function(name, messageType, seqid) { - this.tstack.push([TJSONProtocol.Version, '"' + name + '"', messageType, seqid]); +TJSONProtocol.prototype.writeMessageBegin = function ( + name, + messageType, + seqid, +) { + this.tstack.push([ + TJSONProtocol.Version, + '"' + name + '"', + messageType, + seqid, + ]); }; /** * Serializes the end of a Thrift RPC message. */ -TJSONProtocol.prototype.writeMessageEnd = function() { +TJSONProtocol.prototype.writeMessageEnd = function () { var obj = this.tstack.pop(); this.wobj = this.tstack.pop(); this.wobj.push(obj); - this.wbuf = '[' + this.wobj.join(',') + ']'; + this.wbuf = "[" + this.wobj.join(",") + "]"; // we assume there is nothing more to come so we write this.trans.write(this.wbuf); @@ -129,7 +138,7 @@ TJSONProtocol.prototype.writeMessageEnd = function() { * Serializes the beginning of a struct. * @param {string} name - The name of the struct. */ -TJSONProtocol.prototype.writeStructBegin = function(name) { +TJSONProtocol.prototype.writeStructBegin = function (name) { this.tpos.push(this.tstack.length); this.tstack.push({}); }; @@ -137,22 +146,22 @@ TJSONProtocol.prototype.writeStructBegin = function(name) { /** * Serializes the end of a struct. */ -TJSONProtocol.prototype.writeStructEnd = function() { +TJSONProtocol.prototype.writeStructEnd = function () { var p = this.tpos.pop(); var struct = this.tstack[p]; - var str = '{'; + var str = "{"; var first = true; for (var key in struct) { if (first) { first = false; } else { - str += ','; + str += ","; } - str += key + ':' + struct[key]; + str += key + ":" + struct[key]; } - str += '}'; + str += "}"; this.tstack[p] = str; this.writeToTransportIfStackIsFlushable(); @@ -164,26 +173,27 @@ TJSONProtocol.prototype.writeStructEnd = function() { * @param {Thrift.Protocol.Type} fieldType - The data type of the field. * @param {number} fieldId - The field's unique identifier. */ -TJSONProtocol.prototype.writeFieldBegin = function(name, fieldType, fieldId) { +TJSONProtocol.prototype.writeFieldBegin = function (name, fieldType, fieldId) { this.tpos.push(this.tstack.length); - this.tstack.push({ 'fieldId': '"' + - fieldId + '"', 'fieldType': TJSONProtocol.Type[fieldType] + this.tstack.push({ + fieldId: '"' + fieldId + '"', + fieldType: TJSONProtocol.Type[fieldType], }); }; /** * Serializes the end of a field. */ -TJSONProtocol.prototype.writeFieldEnd = function() { +TJSONProtocol.prototype.writeFieldEnd = function () { var value = this.tstack.pop(); var fieldInfo = this.tstack.pop(); - if (':' + value === ":[object Object]") { - this.tstack[this.tstack.length - 1][fieldInfo.fieldId] = '{' + - fieldInfo.fieldType + ':' + JSON.stringify(value) + '}'; + if (":" + value === ":[object Object]") { + this.tstack[this.tstack.length - 1][fieldInfo.fieldId] = + "{" + fieldInfo.fieldType + ":" + JSON.stringify(value) + "}"; } else { - this.tstack[this.tstack.length - 1][fieldInfo.fieldId] = '{' + - fieldInfo.fieldType + ':' + value + '}'; + this.tstack[this.tstack.length - 1][fieldInfo.fieldId] = + "{" + fieldInfo.fieldType + ":" + value + "}"; } this.tpos.pop(); @@ -193,8 +203,7 @@ TJSONProtocol.prototype.writeFieldEnd = function() { /** * Serializes the end of the set of fields for a struct. */ -TJSONProtocol.prototype.writeFieldStop = function() { -}; +TJSONProtocol.prototype.writeFieldStop = function () {}; /** * Serializes the beginning of a map collection. @@ -202,16 +211,20 @@ TJSONProtocol.prototype.writeFieldStop = function() { * @param {Thrift.Type} valType - The data type of the value. * @param {number} [size] - The number of elements in the map (ignored). */ -TJSONProtocol.prototype.writeMapBegin = function(keyType, valType, size) { +TJSONProtocol.prototype.writeMapBegin = function (keyType, valType, size) { //size is invalid, we'll set it on end. this.tpos.push(this.tstack.length); - this.tstack.push([TJSONProtocol.Type[keyType], TJSONProtocol.Type[valType], 0]); + this.tstack.push([ + TJSONProtocol.Type[keyType], + TJSONProtocol.Type[valType], + 0, + ]); }; /** * Serializes the end of a map. */ -TJSONProtocol.prototype.writeMapEnd = function() { +TJSONProtocol.prototype.writeMapEnd = function () { var p = this.tpos.pop(); if (p == this.tstack.length) { @@ -219,14 +232,14 @@ TJSONProtocol.prototype.writeMapEnd = function() { } if ((this.tstack.length - p - 1) % 2 !== 0) { - this.tstack.push(''); + this.tstack.push(""); } var size = (this.tstack.length - p - 1) / 2; this.tstack[p][this.tstack[p].length - 1] = size; - var map = '}'; + var map = "}"; var first = true; while (this.tstack.length > p + 1) { var v = this.tstack.pop(); @@ -234,16 +247,18 @@ TJSONProtocol.prototype.writeMapEnd = function() { if (first) { first = false; } else { - map = ',' + map; + map = "," + map; } - if (! isNaN(k)) { k = '"' + k + '"'; } //json "keys" need to be strings - map = k + ':' + v + map; + if (!isNaN(k)) { + k = '"' + k + '"'; + } //json "keys" need to be strings + map = k + ":" + v + map; } - map = '{' + map; + map = "{" + map; this.tstack[p].push(map); - this.tstack[p] = '[' + this.tstack[p].join(',') + ']'; + this.tstack[p] = "[" + this.tstack[p].join(",") + "]"; this.writeToTransportIfStackIsFlushable(); }; @@ -253,7 +268,7 @@ TJSONProtocol.prototype.writeMapEnd = function() { * @param {Thrift.Type} elemType - The data type of the elements. * @param {number} size - The number of elements in the list. */ -TJSONProtocol.prototype.writeListBegin = function(elemType, size) { +TJSONProtocol.prototype.writeListBegin = function (elemType, size) { this.tpos.push(this.tstack.length); this.tstack.push([TJSONProtocol.Type[elemType], size]); }; @@ -261,7 +276,7 @@ TJSONProtocol.prototype.writeListBegin = function(elemType, size) { /** * Serializes the end of a list. */ -TJSONProtocol.prototype.writeListEnd = function() { +TJSONProtocol.prototype.writeListEnd = function () { var p = this.tpos.pop(); while (this.tstack.length > p + 1) { @@ -270,7 +285,7 @@ TJSONProtocol.prototype.writeListEnd = function() { this.tstack[p].push(tmpVal); } - this.tstack[p] = '[' + this.tstack[p].join(',') + ']'; + this.tstack[p] = "[" + this.tstack[p].join(",") + "]"; this.writeToTransportIfStackIsFlushable(); }; @@ -280,15 +295,15 @@ TJSONProtocol.prototype.writeListEnd = function() { * @param {Thrift.Type} elemType - The data type of the elements. * @param {number} size - The number of elements in the list. */ -TJSONProtocol.prototype.writeSetBegin = function(elemType, size) { - this.tpos.push(this.tstack.length); - this.tstack.push([TJSONProtocol.Type[elemType], size]); +TJSONProtocol.prototype.writeSetBegin = function (elemType, size) { + this.tpos.push(this.tstack.length); + this.tstack.push([TJSONProtocol.Type[elemType], size]); }; /** * Serializes the end of a set. */ -TJSONProtocol.prototype.writeSetEnd = function() { +TJSONProtocol.prototype.writeSetEnd = function () { var p = this.tpos.pop(); while (this.tstack.length > p + 1) { @@ -297,33 +312,33 @@ TJSONProtocol.prototype.writeSetEnd = function() { this.tstack[p].push(tmpVal); } - this.tstack[p] = '[' + this.tstack[p].join(',') + ']'; + this.tstack[p] = "[" + this.tstack[p].join(",") + "]"; this.writeToTransportIfStackIsFlushable(); }; /** Serializes a boolean */ -TJSONProtocol.prototype.writeBool = function(bool) { +TJSONProtocol.prototype.writeBool = function (bool) { this.tstack.push(bool ? 1 : 0); }; /** Serializes a number */ -TJSONProtocol.prototype.writeByte = function(byte) { +TJSONProtocol.prototype.writeByte = function (byte) { this.tstack.push(byte); }; /** Serializes a number */ -TJSONProtocol.prototype.writeI16 = function(i16) { +TJSONProtocol.prototype.writeI16 = function (i16) { this.tstack.push(i16); }; /** Serializes a number */ -TJSONProtocol.prototype.writeI32 = function(i32) { +TJSONProtocol.prototype.writeI32 = function (i32) { this.tstack.push(i32); }; /** Serializes a number */ -TJSONProtocol.prototype.writeI64 = function(i64) { +TJSONProtocol.prototype.writeI64 = function (i64) { if (i64 instanceof Int64) { this.tstack.push(Int64Util.toDecimalString(i64)); } else { @@ -332,69 +347,81 @@ TJSONProtocol.prototype.writeI64 = function(i64) { }; /** Serializes a number */ -TJSONProtocol.prototype.writeDouble = function(dub) { +TJSONProtocol.prototype.writeDouble = function (dub) { this.tstack.push(dub); }; /** Serializes a string */ -TJSONProtocol.prototype.writeString = function(arg) { +TJSONProtocol.prototype.writeString = function (arg) { // We do not encode uri components for wire transfer: if (arg === null) { - this.tstack.push(null); + this.tstack.push(null); } else { - if (typeof arg === 'string') { - var str = arg; - } else if (arg instanceof Buffer) { - var str = arg.toString('utf8'); - } else { - throw new Error('writeString called without a string/Buffer argument: ' + arg); - } + if (typeof arg === "string") { + var str = arg; + } else if (arg instanceof Buffer) { + var str = arg.toString("utf8"); + } else { + throw new Error( + "writeString called without a string/Buffer argument: " + arg, + ); + } - // concat may be slower than building a byte buffer - var escapedString = ''; - for (var i = 0; i < str.length; i++) { - var ch = str.charAt(i); // a single double quote: " - if (ch === '\"') { - escapedString += '\\\"'; // write out as: \" - } else if (ch === '\\') { // a single backslash: \ - escapedString += '\\\\'; // write out as: \\ - /* Currently escaped forward slashes break TJSONProtocol. - * As it stands, we can simply pass forward slashes into - * our strings across the wire without being escaped. - * I think this is the protocol's bug, not thrift.js - * } else if(ch === '/') { // a single forward slash: / - * escapedString += '\\/'; // write out as \/ - * } - */ - } else if (ch === '\b') { // a single backspace: invisible - escapedString += '\\b'; // write out as: \b" - } else if (ch === '\f') { // a single formfeed: invisible - escapedString += '\\f'; // write out as: \f" - } else if (ch === '\n') { // a single newline: invisible - escapedString += '\\n'; // write out as: \n" - } else if (ch === '\r') { // a single return: invisible - escapedString += '\\r'; // write out as: \r" - } else if (ch === '\t') { // a single tab: invisible - escapedString += '\\t'; // write out as: \t" - } else { - escapedString += ch; // Else it need not be escaped - } + // concat may be slower than building a byte buffer + var escapedString = ""; + for (var i = 0; i < str.length; i++) { + var ch = str.charAt(i); // a single double quote: " + if (ch === '\"') { + escapedString += '\\\"'; // write out as: \" + } else if (ch === "\\") { + // a single backslash: \ + escapedString += "\\\\"; // write out as: \\ + /* Currently escaped forward slashes break TJSONProtocol. + * As it stands, we can simply pass forward slashes into + * our strings across the wire without being escaped. + * I think this is the protocol's bug, not thrift.js + * } else if(ch === '/') { // a single forward slash: / + * escapedString += '\\/'; // write out as \/ + * } + */ + } else if (ch === "\b") { + // a single backspace: invisible + escapedString += "\\b"; // write out as: \b" + } else if (ch === "\f") { + // a single formfeed: invisible + escapedString += "\\f"; // write out as: \f" + } else if (ch === "\n") { + // a single newline: invisible + escapedString += "\\n"; // write out as: \n" + } else if (ch === "\r") { + // a single return: invisible + escapedString += "\\r"; // write out as: \r" + } else if (ch === "\t") { + // a single tab: invisible + escapedString += "\\t"; // write out as: \t" + } else { + escapedString += ch; // Else it need not be escaped } - this.tstack.push('"' + escapedString + '"'); + } + this.tstack.push('"' + escapedString + '"'); } }; /** Serializes a string */ -TJSONProtocol.prototype.writeBinary = function(arg) { - if (typeof arg === 'string') { - var buf = new Buffer(arg, 'binary'); - } else if (arg instanceof Buffer || - Object.prototype.toString.call(arg) == '[object Uint8Array]') { +TJSONProtocol.prototype.writeBinary = function (arg) { + if (typeof arg === "string") { + var buf = new Buffer(arg, "binary"); + } else if ( + arg instanceof Buffer || + Object.prototype.toString.call(arg) == "[object Uint8Array]" + ) { var buf = arg; } else { - throw new Error('writeBinary called without a string/Buffer argument: ' + arg); + throw new Error( + "writeBinary called without a string/Buffer argument: " + arg, + ); } - this.tstack.push('"' + buf.toString('base64') + '"'); + this.tstack.push('"' + buf.toString("base64") + '"'); }; /** @@ -408,7 +435,7 @@ TJSONProtocol.prototype.writeBinary = function(arg) { * Deserializes the beginning of a message. * @returns {AnonReadMessageBeginReturn} */ -TJSONProtocol.prototype.readMessageBegin = function() { +TJSONProtocol.prototype.readMessageBegin = function () { this.rstack = []; this.rpos = []; @@ -419,7 +446,8 @@ TJSONProtocol.prototype.readMessageBegin = function() { } var cursor = transBuf.readIndex; - if (transBuf.buf[cursor] !== 0x5B) { //[ + if (transBuf.buf[cursor] !== 0x5b) { + //[ throw new Error("Malformed JSON input, no opening bracket"); } @@ -432,22 +460,27 @@ TJSONProtocol.prototype.readMessageBegin = function() { var chr = transBuf.buf[cursor]; //we use hexa charcode here because data[i] returns an int and not a char if (inString) { - if (chr === 0x22) { //" + if (chr === 0x22) { + //" inString = false; - } else if (chr === 0x5C) { //\ + } else if (chr === 0x5c) { + //\ //escaped character, skip cursor += 1; } } else { - if (chr === 0x5B) { //[ + if (chr === 0x5b) { + //[ openBracketCount += 1; - } else if (chr === 0x5D) { //] + } else if (chr === 0x5d) { + //] openBracketCount -= 1; if (openBracketCount === 0) { //end of json message detected break; } - } else if (chr === 0x22) { //" + } else if (chr === 0x22) { + //" inString = true; } } @@ -459,13 +492,15 @@ TJSONProtocol.prototype.readMessageBegin = function() { } //Reconstitute the JSON object and conume the necessary bytes - this.robj = json_parse(transBuf.buf.slice(transBuf.readIndex, cursor+1).toString()); + this.robj = json_parse( + transBuf.buf.slice(transBuf.readIndex, cursor + 1).toString(), + ); this.trans.consume(cursor + 1 - transBuf.readIndex); //Verify the protocol version var version = this.robj.shift(); if (version != TJSONProtocol.Version) { - throw new Error('Wrong thrift protocol version: ' + version); + throw new Error("Wrong thrift protocol version: " + version); } //Objectify the thrift message {name/type/sequence-number} for return @@ -479,17 +514,16 @@ TJSONProtocol.prototype.readMessageBegin = function() { }; /** Deserializes the end of a message. */ -TJSONProtocol.prototype.readMessageEnd = function() { -}; +TJSONProtocol.prototype.readMessageEnd = function () {}; /** * Deserializes the beginning of a struct. * @param {string} [name] - The name of the struct (ignored) * @returns {object} - An object with an empty string fname property */ -TJSONProtocol.prototype.readStructBegin = function() { +TJSONProtocol.prototype.readStructBegin = function () { var r = {}; - r.fname = ''; + r.fname = ""; //incase this is an array of structs if (this.rstack[this.rstack.length - 1] instanceof Array) { @@ -500,7 +534,7 @@ TJSONProtocol.prototype.readStructBegin = function() { }; /** Deserializes the end of a struct. */ -TJSONProtocol.prototype.readStructEnd = function() { +TJSONProtocol.prototype.readStructEnd = function () { this.rstack.pop(); }; @@ -515,14 +549,14 @@ TJSONProtocol.prototype.readStructEnd = function() { * Deserializes the beginning of a field. * @returns {AnonReadFieldBeginReturn} */ -TJSONProtocol.prototype.readFieldBegin = function() { +TJSONProtocol.prototype.readFieldBegin = function () { var r = {}; var fid = -1; var ftype = Type.STOP; //get a fieldId - for (var f in (this.rstack[this.rstack.length - 1])) { + for (var f in this.rstack[this.rstack.length - 1]) { if (f === null) { continue; } @@ -543,17 +577,18 @@ TJSONProtocol.prototype.readFieldBegin = function() { if (fid != -1) { //should only be 1 of these but this is the only //way to match a key - for (var i in (this.rstack[this.rstack.length - 1])) { + for (var i in this.rstack[this.rstack.length - 1]) { if (TJSONProtocol.RType[i] === null) { continue; } ftype = TJSONProtocol.RType[i]; - this.rstack[this.rstack.length - 1] = this.rstack[this.rstack.length - 1][i]; + this.rstack[this.rstack.length - 1] = + this.rstack[this.rstack.length - 1][i]; } } - r.fname = ''; + r.fname = ""; r.ftype = ftype; r.fid = fid; @@ -561,7 +596,7 @@ TJSONProtocol.prototype.readFieldBegin = function() { }; /** Deserializes the end of a field. */ -TJSONProtocol.prototype.readFieldEnd = function() { +TJSONProtocol.prototype.readFieldEnd = function () { var pos = this.rpos.pop(); //get back to the right place in the stack @@ -581,7 +616,7 @@ TJSONProtocol.prototype.readFieldEnd = function() { * Deserializes the beginning of a map. * @returns {AnonReadMapBeginReturn} */ -TJSONProtocol.prototype.readMapBegin = function() { +TJSONProtocol.prototype.readMapBegin = function () { var map = this.rstack.pop(); var first = map.shift(); if (first instanceof Array) { @@ -595,7 +630,6 @@ TJSONProtocol.prototype.readMapBegin = function() { r.vtype = TJSONProtocol.RType[map.shift()]; r.size = map.shift(); - this.rpos.push(this.rstack.length); this.rstack.push(map.shift()); @@ -603,7 +637,7 @@ TJSONProtocol.prototype.readMapBegin = function() { }; /** Deserializes the end of a map. */ -TJSONProtocol.prototype.readMapEnd = function() { +TJSONProtocol.prototype.readMapEnd = function () { this.readFieldEnd(); }; @@ -617,7 +651,7 @@ TJSONProtocol.prototype.readMapEnd = function() { * Deserializes the beginning of a list. * @returns {AnonReadColBeginReturn} */ -TJSONProtocol.prototype.readListBegin = function() { +TJSONProtocol.prototype.readListBegin = function () { var list = this.rstack[this.rstack.length - 1]; var r = {}; @@ -631,7 +665,7 @@ TJSONProtocol.prototype.readListBegin = function() { }; /** Deserializes the end of a list. */ -TJSONProtocol.prototype.readListEnd = function() { +TJSONProtocol.prototype.readListEnd = function () { var pos = this.rpos.pop() - 2; var st = this.rstack; st.pop(); @@ -644,33 +678,33 @@ TJSONProtocol.prototype.readListEnd = function() { * Deserializes the beginning of a set. * @returns {AnonReadColBeginReturn} */ -TJSONProtocol.prototype.readSetBegin = function() { +TJSONProtocol.prototype.readSetBegin = function () { return this.readListBegin(); }; /** Deserializes the end of a set. */ -TJSONProtocol.prototype.readSetEnd = function() { +TJSONProtocol.prototype.readSetEnd = function () { return this.readListEnd(); }; -TJSONProtocol.prototype.readBool = function() { - return this.readValue() == '1'; +TJSONProtocol.prototype.readBool = function () { + return this.readValue() == "1"; }; -TJSONProtocol.prototype.readByte = function() { +TJSONProtocol.prototype.readByte = function () { return this.readI32(); }; -TJSONProtocol.prototype.readI16 = function() { +TJSONProtocol.prototype.readI16 = function () { return this.readI32(); }; -TJSONProtocol.prototype.readI32 = function(f) { +TJSONProtocol.prototype.readI32 = function (f) { return +this.readValue(); -} +}; /** Returns the next value found in the protocol buffer */ -TJSONProtocol.prototype.readValue = function(f) { +TJSONProtocol.prototype.readValue = function (f) { if (f === undefined) { f = this.rstack[this.rstack.length - 1]; } @@ -702,9 +736,9 @@ TJSONProtocol.prototype.readValue = function(f) { return r.value; }; -TJSONProtocol.prototype.readI64 = function() { - var n = this.readValue() - if (typeof n === 'string') { +TJSONProtocol.prototype.readI64 = function () { + var n = this.readValue(); + if (typeof n === "string") { // Assuming no one is sending in 1.11111e+33 format return Int64Util.fromDecimalString(n); } else { @@ -712,15 +746,15 @@ TJSONProtocol.prototype.readI64 = function() { } }; -TJSONProtocol.prototype.readDouble = function() { +TJSONProtocol.prototype.readDouble = function () { return this.readI32(); }; -TJSONProtocol.prototype.readBinary = function() { - return new Buffer(this.readValue(), 'base64'); +TJSONProtocol.prototype.readBinary = function () { + return new Buffer(this.readValue(), "base64"); }; -TJSONProtocol.prototype.readString = function() { +TJSONProtocol.prototype.readString = function () { return this.readValue(); }; @@ -729,15 +763,15 @@ TJSONProtocol.prototype.readString = function() { * @readonly * @returns {Thrift.Transport} The underlying transport. */ -TJSONProtocol.prototype.getTransport = function() { +TJSONProtocol.prototype.getTransport = function () { return this.trans; }; /** * Method to arbitrarily skip over data */ -TJSONProtocol.prototype.skip = function(type) { - switch (type) { +TJSONProtocol.prototype.skip = function (type) { + switch (type) { case Type.BOOL: this.readBool(); break; @@ -794,6 +828,6 @@ TJSONProtocol.prototype.skip = function(type) { this.readListEnd(); break; default: - throw new Error("Invalid type: " + type); + throw new Error("Invalid type: " + type); } }; diff --git a/lib/nodejs/lib/thrift/log.js b/lib/nodejs/lib/thrift/log.js index 053e813618e..82d8a222cd7 100644 --- a/lib/nodejs/lib/thrift/log.js +++ b/lib/nodejs/lib/thrift/log.js @@ -17,17 +17,17 @@ * under the License. */ -var util = require('util'); +var util = require("util"); var disabled = function () {}; var logFunc = console.log; -var logLevel = 'error'; // default level +var logLevel = "error"; // default level function factory(level) { return function () { // better use spread syntax, but due to compatibility, // use legacy method here. - var args = ['thrift: [' + level + '] '].concat(Array.from(arguments)); + var args = ["thrift: [" + level + "] "].concat(Array.from(arguments)); return logFunc(util.format.apply(null, args)); }; } @@ -42,22 +42,22 @@ exports.setLogFunc = function (func) { logFunc = func; }; -var setLogLevel = exports.setLogLevel = function (level) { +var setLogLevel = (exports.setLogLevel = function (level) { trace = debug = error = warning = info = disabled; logLevel = level; switch (logLevel) { - case 'trace': - trace = factory('TRACE'); - case 'debug': - debug = factory('DEBUG'); - case 'error': - error = factory('ERROR'); - case 'warning': - warning = factory('WARN'); - case 'info': - info = factory('INFO'); + case "trace": + trace = factory("TRACE"); + case "debug": + debug = factory("DEBUG"); + case "error": + error = factory("ERROR"); + case "warning": + warning = factory("WARN"); + case "info": + info = factory("INFO"); } -}; +}); // set default setLogLevel(logLevel); diff --git a/lib/nodejs/lib/thrift/multiplexed_processor.js b/lib/nodejs/lib/thrift/multiplexed_processor.js index 67b62f7a29d..864d66d3257 100644 --- a/lib/nodejs/lib/thrift/multiplexed_processor.js +++ b/lib/nodejs/lib/thrift/multiplexed_processor.js @@ -16,31 +16,38 @@ * specific language governing permissions and limitations * under the License. */ -var Thrift = require('./thrift'); +var Thrift = require("./thrift"); exports.MultiplexedProcessor = MultiplexedProcessor; function MultiplexedProcessor(stream, options) { this.services = {}; -}; +} -MultiplexedProcessor.prototype.registerProcessor = function(name, handler) { +MultiplexedProcessor.prototype.registerProcessor = function (name, handler) { this.services[name] = handler; }; -MultiplexedProcessor.prototype.process = function(inp, out) { +MultiplexedProcessor.prototype.process = function (inp, out) { var begin = inp.readMessageBegin(); - if (begin.mtype != Thrift.MessageType.CALL && begin.mtype != Thrift.MessageType.ONEWAY) { - throw new Thrift.TException('TMultiplexedProcessor: Unexpected message type'); + if ( + begin.mtype != Thrift.MessageType.CALL && + begin.mtype != Thrift.MessageType.ONEWAY + ) { + throw new Thrift.TException( + "TMultiplexedProcessor: Unexpected message type", + ); } - var p = begin.fname.split(':'); + var p = begin.fname.split(":"); var sname = p[0]; var fname = p[1]; - if (! (sname in this.services)) { - throw new Thrift.TException('TMultiplexedProcessor: Unknown service: ' + sname); + if (!(sname in this.services)) { + throw new Thrift.TException( + "TMultiplexedProcessor: Unknown service: " + sname, + ); } //construct a proxy object which stubs the readMessageBegin @@ -51,11 +58,11 @@ MultiplexedProcessor.prototype.process = function(inp, out) { inpProxy[attr] = inp[attr]; } - inpProxy.readMessageBegin = function() { + inpProxy.readMessageBegin = function () { return { fname: fname, mtype: begin.mtype, - rseqid: begin.rseqid + rseqid: begin.rseqid, }; }; diff --git a/lib/nodejs/lib/thrift/multiplexed_protocol.js b/lib/nodejs/lib/thrift/multiplexed_protocol.js index d078aa2266f..1d2df96341b 100644 --- a/lib/nodejs/lib/thrift/multiplexed_protocol.js +++ b/lib/nodejs/lib/thrift/multiplexed_protocol.js @@ -16,55 +16,69 @@ * specific language governing permissions and limitations * under the License. */ -var util = require('util'); -var Thrift = require('./thrift'); +var util = require("util"); +var Thrift = require("./thrift"); exports.Multiplexer = Multiplexer; function Wrapper(serviceName, protocol, connection) { - function MultiplexProtocol(trans, strictRead, strictWrite) { protocol.call(this, trans, strictRead, strictWrite); - }; + } util.inherits(MultiplexProtocol, protocol); - MultiplexProtocol.prototype.writeMessageBegin = function(name, type, seqid) { + MultiplexProtocol.prototype.writeMessageBegin = function (name, type, seqid) { if (type == Thrift.MessageType.CALL || type == Thrift.MessageType.ONEWAY) { connection.seqId2Service[seqid] = serviceName; - MultiplexProtocol.super_.prototype.writeMessageBegin.call(this, - serviceName + ":" + name, - type, - seqid); + MultiplexProtocol.super_.prototype.writeMessageBegin.call( + this, + serviceName + ":" + name, + type, + seqid, + ); } else { - MultiplexProtocol.super_.prototype.writeMessageBegin.call(this, name, type, seqid); + MultiplexProtocol.super_.prototype.writeMessageBegin.call( + this, + name, + type, + seqid, + ); } }; return MultiplexProtocol; -}; +} function Multiplexer() { this.seqid = 0; -}; +} -Multiplexer.prototype.createClient = function(serviceName, ServiceClient, connection) { +Multiplexer.prototype.createClient = function ( + serviceName, + ServiceClient, + connection, +) { if (ServiceClient.Client) { ServiceClient = ServiceClient.Client; } - var writeCb = function(buf, seqid) { - connection.write(buf,seqid); + var writeCb = function (buf, seqid) { + connection.write(buf, seqid); }; var transport = new connection.transport(undefined, writeCb); - var protocolWrapper = new Wrapper(serviceName, connection.protocol, connection); + var protocolWrapper = new Wrapper( + serviceName, + connection.protocol, + connection, + ); var client = new ServiceClient(transport, protocolWrapper); var self = this; - client.new_seqid = function() { + client.new_seqid = function () { self.seqid += 1; return self.seqid; }; - if (typeof connection.client !== 'object') { + if (typeof connection.client !== "object") { connection.client = {}; } connection.client[serviceName] = client; diff --git a/lib/nodejs/lib/thrift/ohos_connection.js b/lib/nodejs/lib/thrift/ohos_connection.js index 95bf122790a..34afaae1858 100644 --- a/lib/nodejs/lib/thrift/ohos_connection.js +++ b/lib/nodejs/lib/thrift/ohos_connection.js @@ -16,15 +16,15 @@ * specific language governing permissions and limitations * under the License. */ -var util = require('util'); -var EventEmitter = require('events').EventEmitter; -var thrift = require('./thrift'); +var util = require("util"); +var EventEmitter = require("events").EventEmitter; +var thrift = require("./thrift"); -var TBufferedTransport = require('./buffered_transport'); -var TBinaryProtocol = require('./binary_protocol'); -var InputBufferUnderrunError = require('./input_buffer_underrun_error'); +var TBufferedTransport = require("./buffered_transport"); +var TBinaryProtocol = require("./binary_protocol"); +var InputBufferUnderrunError = require("./input_buffer_underrun_error"); -var createClient = require('./create_client'); +var createClient = require("./create_client"); /** * @class @@ -69,7 +69,7 @@ var createClient = require('./create_client'); * semantics implemented over the OpenHarmonyOS http.request() method. * @see {@link createOhosConnection} */ -var OhosConnection = exports.OhosConnection = function(options) { +var OhosConnection = (exports.OhosConnection = function (options) { //Initialize the emitter base object EventEmitter.call(this); @@ -78,12 +78,12 @@ var OhosConnection = exports.OhosConnection = function(options) { this.options = options || {}; this.host = this.options.host; this.port = this.options.port; - this.path = this.options.path || '/'; + this.path = this.options.path || "/"; //OpenHarmonyOS needs URL for initiating an HTTP request. this.url = this.port === 80 - ? this.host.replace(/\/$/, '') + this.path - : this.host.replace(/\/$/, '') + ':' + this.port + this.path; + ? this.host.replace(/\/$/, "") + this.path + : this.host.replace(/\/$/, "") + ":" + this.port + this.path; this.transport = this.options.transport || TBufferedTransport; this.protocol = this.options.protocol || TBinaryProtocol; //Inherit method from OpenHarmonyOS HTTP module @@ -91,17 +91,17 @@ var OhosConnection = exports.OhosConnection = function(options) { //Prepare HTTP request options this.requestOptions = { - method: 'POST', + method: "POST", header: this.options.header || {}, readTimeout: this.options.readTimeout || 60000, - connectTimeout: this.options.connectTimeout || 60000 + connectTimeout: this.options.connectTimeout || 60000, }; for (var attrname in this.options.requestOptions) { this.requestOptions[attrname] = this.options.requestOptions[attrname]; } /*jshint -W069 */ - if (!this.requestOptions.header['Connection']) { - this.requestOptions.header['Connection'] = 'keep-alive'; + if (!this.requestOptions.header["Connection"]) { + this.requestOptions.header["Connection"] = "keep-alive"; } /*jshint +W069 */ @@ -134,60 +134,61 @@ var OhosConnection = exports.OhosConnection = function(options) { delete self.seqId2Service[header.rseqid]; } /*jshint -W083 */ - client._reqs[dummy_seqid] = function(err, success){ + client._reqs[dummy_seqid] = function (err, success) { transport_with_data.commitPosition(); var clientCallback = client._reqs[header.rseqid]; delete client._reqs[header.rseqid]; if (clientCallback) { - process.nextTick(function() { + process.nextTick(function () { clientCallback(err, success); }); } }; /*jshint +W083 */ - if(client['recv_' + header.fname]) { - client['recv_' + header.fname](proto, header.mtype, dummy_seqid); + if (client["recv_" + header.fname]) { + client["recv_" + header.fname](proto, header.mtype, dummy_seqid); } else { delete client._reqs[dummy_seqid]; - self.emit("error", - new thrift.TApplicationException( - thrift.TApplicationExceptionType.WRONG_METHOD_NAME, - "Received a response to an unknown RPC function")); + self.emit( + "error", + new thrift.TApplicationException( + thrift.TApplicationExceptionType.WRONG_METHOD_NAME, + "Received a response to an unknown RPC function", + ), + ); } } - } - catch (e) { + } catch (e) { if (e instanceof InputBufferUnderrunError) { transport_with_data.rollbackPosition(); } else { - self.emit('error', e); + self.emit("error", e); } } } - //Response handler ////////////////////////////////////////////////// - this.responseCallback = function(error, response) { + this.responseCallback = function (error, response) { //Response will be a struct like: // https://developer.harmonyos.com/en/docs/documentation/doc-references/js-apis-net-http-0000001168304341#section15920192914312 var data = []; var dataLen = 0; if (error) { - self.emit('error', error); + self.emit("error", error); return; } if (!response || response.responseCode !== 200) { - self.emit('error', new THTTPException(response)); + self.emit("error", new THTTPException(response)); } // With OpenHarmonyOS running in a Browser (e.g. Browserify), chunk // will be a string or an ArrayBuffer. if ( - typeof response.result == 'string' || - Object.prototype.toString.call(response.result) == '[object Uint8Array]' + typeof response.result == "string" || + Object.prototype.toString.call(response.result) == "[object Uint8Array]" ) { // Wrap ArrayBuffer/string in a Buffer so data[i].copy will work data.push(Buffer.from(response.result)); @@ -211,7 +212,7 @@ var OhosConnection = exports.OhosConnection = function(options) { * @event {error} the "error" event is raised upon request failure passing the * Node.js error object to the listener. */ - this.write = function(data) { + this.write = function (data) { //To initiate multiple HTTP requests, we must create an HttpRequest object // for each HTTP request var http = self.createHttp(); @@ -223,7 +224,7 @@ var OhosConnection = exports.OhosConnection = function(options) { opts.extraData = data.toString(); http.request(self.url, opts, self.responseCallback); }; -}; +}); util.inherits(OhosConnection, EventEmitter); /** @@ -236,7 +237,7 @@ util.inherits(OhosConnection, EventEmitter); * @returns {OhosConnection} The connection object. * @see {@link ConnectOptions} */ -exports.createOhosConnection = function(createHttp, host, port, options) { +exports.createOhosConnection = function (createHttp, host, port, options) { options.createHttp = createHttp; options.host = host; options.port = port || 80; @@ -256,6 +257,6 @@ function THTTPException(response) { this.response = response; this.type = thrift.TApplicationExceptionType.PROTOCOL_ERROR; this.message = - 'Received a response with a bad HTTP status code: ' + response.responseCode; + "Received a response with a bad HTTP status code: " + response.responseCode; } util.inherits(THTTPException, thrift.TApplicationException); diff --git a/lib/nodejs/lib/thrift/protocol.js b/lib/nodejs/lib/thrift/protocol.js index a70ebe2872d..6eb88da061b 100644 --- a/lib/nodejs/lib/thrift/protocol.js +++ b/lib/nodejs/lib/thrift/protocol.js @@ -17,6 +17,6 @@ * under the License. */ -module.exports.TBinaryProtocol = require('./binary_protocol'); -module.exports.TCompactProtocol = require('./compact_protocol'); -module.exports.TJSONProtocol = require('./json_protocol'); +module.exports.TBinaryProtocol = require("./binary_protocol"); +module.exports.TCompactProtocol = require("./compact_protocol"); +module.exports.TJSONProtocol = require("./json_protocol"); diff --git a/lib/nodejs/lib/thrift/server.js b/lib/nodejs/lib/thrift/server.js index 16b74eaafc4..80a369fd194 100644 --- a/lib/nodejs/lib/thrift/server.js +++ b/lib/nodejs/lib/thrift/server.js @@ -17,14 +17,14 @@ * under the License. */ -var constants = require('constants'); -var net = require('net'); -var tls = require('tls'); +var constants = require("constants"); +var net = require("net"); +var tls = require("tls"); -var TBufferedTransport = require('./buffered_transport'); -var TBinaryProtocol = require('./binary_protocol'); -var THeaderProtocol = require('./header_protocol'); -var InputBufferUnderrunError = require('./input_buffer_underrun_error'); +var TBufferedTransport = require("./buffered_transport"); +var TBinaryProtocol = require("./binary_protocol"); +var THeaderProtocol = require("./header_protocol"); +var InputBufferUnderrunError = require("./input_buffer_underrun_error"); /** * Create a Thrift server which can serve one or multiple services. @@ -33,75 +33,82 @@ var InputBufferUnderrunError = require('./input_buffer_underrun_error'); * @param {ServerOptions} options - Optional additional server configuration. * @returns {object} - The Apache Thrift Multiplex Server. */ -exports.createMultiplexServer = function(processor, options) { - var transport = (options && options.transport) ? options.transport : TBufferedTransport; - var protocol = (options && options.protocol) ? options.protocol : TBinaryProtocol; +exports.createMultiplexServer = function (processor, options) { + var transport = + options && options.transport ? options.transport : TBufferedTransport; + var protocol = + options && options.protocol ? options.protocol : TBinaryProtocol; function serverImpl(stream) { var self = this; - stream.on('error', function(err) { - self.emit('error', err); + stream.on("error", function (err) { + self.emit("error", err); }); - stream.on('data', transport.receiver(function(transportWithData) { - var input = new protocol(transportWithData); - var outputCb = function(buf) { - try { + stream.on( + "data", + transport.receiver(function (transportWithData) { + var input = new protocol(transportWithData); + var outputCb = function (buf) { + try { stream.write(buf); - } catch (err) { - self.emit('error', err); + } 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 { - processor.process(input, output); - transportWithData.commitPosition(); - } while (true); - } catch (err) { - if (err instanceof InputBufferUnderrunError) { - //The last data in the buffer was not a complete message, wait for the rest - transportWithData.rollbackPosition(); - } - else if (err.message === "Invalid type: undefined") { - //No more data in the buffer - //This trap is a bit hackish - //The next step to improve the node behavior here is to have - // the compiler generated process method throw a more explicit - // error when the network buffer is empty (regardles of the - // protocol/transport stack in use) and replace this heuristic. - // Also transports should probably not force upper layers to - // manage their buffer positions (i.e. rollbackPosition() and - // commitPosition() should be eliminated in lieu of a transport - // encapsulated buffer management strategy.) - transportWithData.rollbackPosition(); + 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; } - else { - //Unexpected error - self.emit('error', err); - stream.end(); + + try { + do { + processor.process(input, output); + transportWithData.commitPosition(); + } while (true); + } catch (err) { + if (err instanceof InputBufferUnderrunError) { + //The last data in the buffer was not a complete message, wait for the rest + transportWithData.rollbackPosition(); + } else if (err.message === "Invalid type: undefined") { + //No more data in the buffer + //This trap is a bit hackish + //The next step to improve the node behavior here is to have + // the compiler generated process method throw a more explicit + // error when the network buffer is empty (regardles of the + // protocol/transport stack in use) and replace this heuristic. + // Also transports should probably not force upper layers to + // manage their buffer positions (i.e. rollbackPosition() and + // commitPosition() should be eliminated in lieu of a transport + // encapsulated buffer management strategy.) + transportWithData.rollbackPosition(); + } else { + //Unexpected error + self.emit("error", err); + stream.end(); + } } - } - })); + }), + ); - stream.on('end', function() { + stream.on("end", function () { stream.end(); }); } if (options && options.tls) { - if (!('secureProtocol' in options.tls) && !('secureOptions' in options.tls)) { + if ( + !("secureProtocol" in options.tls) && + !("secureOptions" in options.tls) + ) { options.tls.secureProtocol = "SSLv23_method"; - options.tls.secureOptions = constants.SSL_OP_NO_SSLv2 | constants.SSL_OP_NO_SSLv3; + options.tls.secureOptions = + constants.SSL_OP_NO_SSLv2 | constants.SSL_OP_NO_SSLv3; } return tls.createServer(options.tls, serverImpl); } else { @@ -115,7 +122,7 @@ exports.createMultiplexServer = function(processor, options) { * @param {ServerOptions} options - Optional additional server configuration. * @returns {object} - The Apache Thrift Multiplex Server. */ -exports.createServer = function(processor, handler, options) { +exports.createServer = function (processor, handler, options) { if (processor.Processor) { processor = processor.Processor; } diff --git a/lib/nodejs/lib/thrift/thrift.js b/lib/nodejs/lib/thrift/thrift.js index f728eacbe48..741a493835d 100644 --- a/lib/nodejs/lib/thrift/thrift.js +++ b/lib/nodejs/lib/thrift/thrift.js @@ -16,9 +16,9 @@ * specific language governing permissions and limitations * under the License. */ -var util = require('util'); +var util = require("util"); -var Type = exports.Type = { +var Type = (exports.Type = { STOP: 0, VOID: 1, BOOL: 2, @@ -35,14 +35,14 @@ var Type = exports.Type = { SET: 14, LIST: 15, UTF8: 16, - UTF16: 17 -}; + UTF16: 17, +}); exports.MessageType = { CALL: 1, REPLY: 2, EXCEPTION: 3, - ONEWAY: 4 + ONEWAY: 4, }; exports.TException = TException; @@ -55,10 +55,10 @@ function TException(message) { this.name = this.constructor.name; this.message = message; -}; +} util.inherits(TException, Error); -var TApplicationExceptionType = exports.TApplicationExceptionType = { +var TApplicationExceptionType = (exports.TApplicationExceptionType = { UNKNOWN: 0, UNKNOWN_METHOD: 1, INVALID_MESSAGE_TYPE: 2, @@ -69,8 +69,8 @@ var TApplicationExceptionType = exports.TApplicationExceptionType = { PROTOCOL_ERROR: 7, INVALID_TRANSFORM: 8, INVALID_PROTOCOL: 9, - UNSUPPORTED_CLIENT_TYPE: 10 -}; + UNSUPPORTED_CLIENT_TYPE: 10, +}); exports.TApplicationException = TApplicationException; @@ -83,73 +83,73 @@ function TApplicationException(type, message) { this.type = type || TApplicationExceptionType.UNKNOWN; this.name = this.constructor.name; this.message = message; -}; +} util.inherits(TApplicationException, TException); -TApplicationException.prototype.read = function(input) { - var ftype; - var ret = input.readStructBegin('TApplicationException'); +TApplicationException.prototype[Symbol.for("read")] = + TApplicationException.prototype.read = function (input) { + var ftype; + var ret = input.readStructBegin("TApplicationException"); - while(1){ + while (1) { ret = input.readFieldBegin(); - if(ret.ftype == Type.STOP) + if (ret.ftype == Type.STOP) break; + + switch (ret.fid) { + case 1: + if (ret.ftype == Type.STRING) { + ret = input.readString(); + this.message = ret; + } else { + ret = input.skip(ret.ftype); + } + break; + case 2: + if (ret.ftype == Type.I32) { + ret = input.readI32(); + this.type = ret; + } else { + ret = input.skip(ret.ftype); + } + break; + default: + ret = input.skip(ret.ftype); break; - - switch(ret.fid){ - case 1: - if( ret.ftype == Type.STRING ){ - ret = input.readString(); - this.message = ret; - } else { - ret = input.skip(ret.ftype); - } - break; - case 2: - if( ret.ftype == Type.I32 ){ - ret = input.readI32(); - this.type = ret; - } else { - ret = input.skip(ret.ftype); - } - break; - default: - ret = input.skip(ret.ftype); - break; } input.readFieldEnd(); - } - input.readStructEnd(); -}; + } + input.readStructEnd(); + }; -TApplicationException.prototype.write = function(output){ - output.writeStructBegin('TApplicationException'); +TApplicationException.prototype[Symbol.for("write")] = + TApplicationException.prototype.write = function (output) { + output.writeStructBegin("TApplicationException"); - if (this.message) { - output.writeFieldBegin('message', Type.STRING, 1); + if (this.message) { + output.writeFieldBegin("message", Type.STRING, 1); output.writeString(this.message); output.writeFieldEnd(); - } + } - if (this.code) { - output.writeFieldBegin('type', Type.I32, 2); + if (this.code) { + output.writeFieldBegin("type", Type.I32, 2); output.writeI32(this.code); output.writeFieldEnd(); - } + } - output.writeFieldStop(); - output.writeStructEnd(); -}; + output.writeFieldStop(); + output.writeStructEnd(); + }; -var TProtocolExceptionType = exports.TProtocolExceptionType = { +var TProtocolExceptionType = (exports.TProtocolExceptionType = { UNKNOWN: 0, INVALID_DATA: 1, NEGATIVE_SIZE: 2, SIZE_LIMIT: 3, BAD_VERSION: 4, NOT_IMPLEMENTED: 5, - DEPTH_LIMIT: 6 -}; - + DEPTH_LIMIT: 6, +}); exports.TProtocolException = TProtocolException; @@ -162,74 +162,74 @@ function TProtocolException(type, message) { this.name = this.constructor.name; this.type = type; this.message = message; -}; +} util.inherits(TProtocolException, Error); -exports.objectLength = function(obj) { +exports.objectLength = function (obj) { return Object.keys(obj).length; }; -exports.inherits = function(constructor, superConstructor) { +exports.inherits = function (constructor, superConstructor) { util.inherits(constructor, superConstructor); }; var copyList, copyMap; -copyList = function(lst, types) { - - if (!lst) {return lst; } +copyList = function (lst, types) { + if (!lst) { + return lst; + } var type; if (types.shift === undefined) { type = types; - } - else { + } else { type = types[0]; } var Type = type; - var len = lst.length, result = [], i, val; + var len = lst.length, + result = [], + i, + val; for (i = 0; i < len; i++) { val = lst[i]; if (type === null) { result.push(val); - } - else if (type === copyMap || type === copyList) { + } else if (type === copyMap || type === copyList) { result.push(type(val, types.slice(1))); - } - else { + } else { result.push(new Type(val)); } } return result; }; -copyMap = function(obj, types){ - - if (!obj) {return obj; } +copyMap = function (obj, types) { + if (!obj) { + return obj; + } var type; if (types.shift === undefined) { type = types; - } - else { + } else { type = types[0]; } var Type = type; - var result = {}, val; - for(var prop in obj) { - if(obj.hasOwnProperty(prop)) { + var result = {}, + val; + for (var prop in obj) { + if (obj.hasOwnProperty(prop)) { val = obj[prop]; if (type === null) { result[prop] = val; - } - else if (type === copyMap || type === copyList) { + } else if (type === copyMap || type === copyList) { result[prop] = type(val, types.slice(1)); - } - else { + } else { result[prop] = new Type(val); } } diff --git a/lib/nodejs/lib/thrift/transport.js b/lib/nodejs/lib/thrift/transport.js index 59daa987d54..b3ba39495b7 100644 --- a/lib/nodejs/lib/thrift/transport.js +++ b/lib/nodejs/lib/thrift/transport.js @@ -17,6 +17,6 @@ * under the License. */ -module.exports.TBufferedTransport = require('./buffered_transport'); -module.exports.TFramedTransport = require('./framed_transport'); -module.exports.InputBufferUnderrunError = require('./input_buffer_underrun_error'); +module.exports.TBufferedTransport = require("./buffered_transport"); +module.exports.TFramedTransport = require("./framed_transport"); +module.exports.InputBufferUnderrunError = require("./input_buffer_underrun_error"); diff --git a/lib/nodejs/lib/thrift/web_server.js b/lib/nodejs/lib/thrift/web_server.js index a33f47aedb7..f49f654b116 100644 --- a/lib/nodejs/lib/thrift/web_server.js +++ b/lib/nodejs/lib/thrift/web_server.js @@ -16,19 +16,20 @@ * specific language governing permissions and limitations * under the License. */ -var http = require('http'); -var https = require('https'); +var http = require("http"); +var https = require("https"); var url = require("url"); var path = require("path"); var fs = require("fs"); var crypto = require("crypto"); -var log = require('./log'); +var log = require("./log"); -var MultiplexedProcessor = require('./multiplexed_processor').MultiplexedProcessor; +var MultiplexedProcessor = + require("./multiplexed_processor").MultiplexedProcessor; -var TBufferedTransport = require('./buffered_transport'); -var TBinaryProtocol = require('./binary_protocol'); -var InputBufferUnderrunError = require('./input_buffer_underrun_error'); +var TBufferedTransport = require("./buffered_transport"); +var TBinaryProtocol = require("./binary_protocol"); +var InputBufferUnderrunError = require("./input_buffer_underrun_error"); // WSFrame constructor and prototype ///////////////////////////////////////////////////////////////////// @@ -82,36 +83,43 @@ var wsFrame = { * @param {Boolean} binEncoding - True for binary encoding, false for text encoding * @returns {Buffer} - The WebSocket frame, ready to send */ - encode: function(data, mask, binEncoding) { - var frame = new Buffer(wsFrame.frameSizeFromData(data, mask)); - //Byte 0 - FIN & OPCODE - frame[0] = wsFrame.fin.FIN + - (binEncoding ? wsFrame.frameOpCodes.BIN : wsFrame.frameOpCodes.TEXT); - //Byte 1 or 1-3 or 1-9 - MASK FLAG & SIZE - var payloadOffset = 2; - if (data.length < 0x7E) { - frame[1] = data.length + (mask ? wsFrame.mask.TO_SERVER : wsFrame.mask.TO_CLIENT); - } else if (data.length < 0xFFFF) { - frame[1] = 0x7E + (mask ? wsFrame.mask.TO_SERVER : wsFrame.mask.TO_CLIENT); - frame.writeUInt16BE(data.length, 2, true); - payloadOffset = 4; - } else { - frame[1] = 0x7F + (mask ? wsFrame.mask.TO_SERVER : wsFrame.mask.TO_CLIENT); - frame.writeUInt32BE(0, 2, true); - frame.writeUInt32BE(data.length, 6, true); - payloadOffset = 10; - } - //MASK - if (mask) { - mask.copy(frame, payloadOffset, 0, 4); - payloadOffset += 4; - } - //Payload - data.copy(frame, payloadOffset); - if (mask) { - wsFrame.applyMask(frame.slice(payloadOffset), frame.slice(payloadOffset-4,payloadOffset)); - } - return frame; + encode: function (data, mask, binEncoding) { + var frame = new Buffer(wsFrame.frameSizeFromData(data, mask)); + //Byte 0 - FIN & OPCODE + frame[0] = + wsFrame.fin.FIN + + (binEncoding ? wsFrame.frameOpCodes.BIN : wsFrame.frameOpCodes.TEXT); + //Byte 1 or 1-3 or 1-9 - MASK FLAG & SIZE + var payloadOffset = 2; + if (data.length < 0x7e) { + frame[1] = + data.length + (mask ? wsFrame.mask.TO_SERVER : wsFrame.mask.TO_CLIENT); + } else if (data.length < 0xffff) { + frame[1] = + 0x7e + (mask ? wsFrame.mask.TO_SERVER : wsFrame.mask.TO_CLIENT); + frame.writeUInt16BE(data.length, 2, true); + payloadOffset = 4; + } else { + frame[1] = + 0x7f + (mask ? wsFrame.mask.TO_SERVER : wsFrame.mask.TO_CLIENT); + frame.writeUInt32BE(0, 2, true); + frame.writeUInt32BE(data.length, 6, true); + payloadOffset = 10; + } + //MASK + if (mask) { + mask.copy(frame, payloadOffset, 0, 4); + payloadOffset += 4; + } + //Payload + data.copy(frame, payloadOffset); + if (mask) { + wsFrame.applyMask( + frame.slice(payloadOffset), + frame.slice(payloadOffset - 4, payloadOffset), + ); + } + return frame; }, /** @@ -127,7 +135,7 @@ var wsFrame = { * @property {Boolean} FIN - True is the message is complete */ - /** Decodes a WebSocket frame + /** Decodes a WebSocket frame * * @param {Buffer} frame - The raw inbound frame, if this is a continuation * frame it must have a mask property with the mask. @@ -135,54 +143,55 @@ var wsFrame = { * * @see {@link WSDecodeResult} */ - decode: function(frame) { - var result = { - data: null, - mask: null, - binEncoding: false, - nextFrame: null, - FIN: true - }; - - //Byte 0 - FIN & OPCODE - if (wsFrame.fin.FIN != (frame[0] & wsFrame.fin.FIN)) { - result.FIN = false; - } - result.binEncoding = (wsFrame.frameOpCodes.BIN == (frame[0] & wsFrame.frameOpCodes.BIN)); - //Byte 1 or 1-3 or 1-9 - SIZE - var lenByte = (frame[1] & 0x0000007F); - var len = lenByte; - var dataOffset = 2; - if (lenByte == 0x7E) { - len = frame.readUInt16BE(2); - dataOffset = 4; - } else if (lenByte == 0x7F) { - len = frame.readUInt32BE(6); - dataOffset = 10; - } - //MASK - if (wsFrame.mask.TO_SERVER == (frame[1] & wsFrame.mask.TO_SERVER)) { - result.mask = new Buffer(4); - frame.copy(result.mask, 0, dataOffset, dataOffset + 4); - dataOffset += 4; - } - //Payload - result.data = new Buffer(len); - frame.copy(result.data, 0, dataOffset, dataOffset+len); - if (result.mask) { - wsFrame.applyMask(result.data, result.mask); - } - //Next Frame - if (frame.length > dataOffset+len) { - result.nextFrame = new Buffer(frame.length - (dataOffset+len)); - frame.copy(result.nextFrame, 0, dataOffset+len, frame.length); - } - //Don't forward control frames - if (frame[0] & wsFrame.frameOpCodes.FINCTRL) { - result.data = null; - } + decode: function (frame) { + var result = { + data: null, + mask: null, + binEncoding: false, + nextFrame: null, + FIN: true, + }; + + //Byte 0 - FIN & OPCODE + if (wsFrame.fin.FIN != (frame[0] & wsFrame.fin.FIN)) { + result.FIN = false; + } + result.binEncoding = + wsFrame.frameOpCodes.BIN == (frame[0] & wsFrame.frameOpCodes.BIN); + //Byte 1 or 1-3 or 1-9 - SIZE + var lenByte = frame[1] & 0x0000007f; + var len = lenByte; + var dataOffset = 2; + if (lenByte == 0x7e) { + len = frame.readUInt16BE(2); + dataOffset = 4; + } else if (lenByte == 0x7f) { + len = frame.readUInt32BE(6); + dataOffset = 10; + } + //MASK + if (wsFrame.mask.TO_SERVER == (frame[1] & wsFrame.mask.TO_SERVER)) { + result.mask = new Buffer(4); + frame.copy(result.mask, 0, dataOffset, dataOffset + 4); + dataOffset += 4; + } + //Payload + result.data = new Buffer(len); + frame.copy(result.data, 0, dataOffset, dataOffset + len); + if (result.mask) { + wsFrame.applyMask(result.data, result.mask); + } + //Next Frame + if (frame.length > dataOffset + len) { + result.nextFrame = new Buffer(frame.length - (dataOffset + len)); + frame.copy(result.nextFrame, 0, dataOffset + len, frame.length); + } + //Don't forward control frames + if (frame[0] & wsFrame.frameOpCodes.FINCTRL) { + result.data = null; + } - return result; + return result; }, /** Masks/Unmasks data @@ -190,12 +199,12 @@ var wsFrame = { * @param {Buffer} data - data to mask/unmask in place * @param {Buffer} mask - the mask */ - applyMask: function(data, mask){ + applyMask: function (data, mask) { //TODO: look into xoring words at a time var dataLen = data.length; var maskLen = mask.length; for (var i = 0; i < dataLen; i++) { - data[i] = data[i] ^ mask[i%maskLen]; + data[i] = data[i] ^ mask[i % maskLen]; } }, @@ -204,35 +213,34 @@ var wsFrame = { * @param {Buffer} data - data.length is the assumed payload size * @param {Boolean} mask - true if a mask will be sent (TO_SERVER) */ - frameSizeFromData: function(data, mask) { + frameSizeFromData: function (data, mask) { var headerSize = 10; - if (data.length < 0x7E) { + if (data.length < 0x7e) { headerSize = 2; - } else if (data.length < 0xFFFF) { + } else if (data.length < 0xffff) { headerSize = 4; } return headerSize + data.length + (mask ? 4 : 0); }, frameOpCodes: { - CONT: 0x00, - TEXT: 0x01, - BIN: 0x02, - CTRL: 0x80 + CONT: 0x00, + TEXT: 0x01, + BIN: 0x02, + CTRL: 0x80, }, mask: { TO_SERVER: 0x80, - TO_CLIENT: 0x00 + TO_CLIENT: 0x00, }, fin: { CONT: 0x00, - FIN: 0x80 - } + FIN: 0x80, + }, }; - // createWebServer constructor and options ///////////////////////////////////////////////////////////////////// @@ -272,20 +280,20 @@ var wsFrame = { * @param {ServerOptions} options - The server configuration. * @returns {object} - The Apache Thrift Web Server. */ -exports.createWebServer = function(options) { +exports.createWebServer = function (options) { var baseDir = options.files; var contentTypesByExtension = { - '.txt': 'text/plain', - '.html': 'text/html', - '.css': 'text/css', - '.xml': 'application/xml', - '.json': 'application/json', - '.js': 'application/javascript', - '.jpg': 'image/jpeg', - '.jpeg': 'image/jpeg', - '.gif': 'image/gif', - '.png': 'image/png', - '.svg': 'image/svg+xml' + ".txt": "text/plain", + ".html": "text/html", + ".css": "text/css", + ".xml": "application/xml", + ".json": "application/json", + ".js": "application/javascript", + ".jpg": "image/jpeg", + ".jpeg": "image/jpeg", + ".gif": "image/gif", + ".png": "image/png", + ".svg": "image/svg+xml", }; //Setup all of the services @@ -302,8 +310,9 @@ exports.createWebServer = function(options) { // IDL Compiler generated class housing the processor. Also, the options property // for a Processor has been called both cls and processor at different times. We // support any of the four possibilities here. - var processor = (svcObj.processor) ? (svcObj.processor.Processor || svcObj.processor) : - (svcObj.cls.Processor || svcObj.cls); + var processor = svcObj.processor + ? svcObj.processor.Processor || svcObj.processor + : svcObj.cls.Processor || svcObj.cls; //Processors can be supplied as constructed objects with handlers already embedded, // if a handler is provided we construct a new processor, if not we use the processor // object directly @@ -322,9 +331,18 @@ exports.createWebServer = function(options) { if (request.headers.origin && options.cors) { if (options.cors["*"] || options.cors[request.headers.origin]) { //Allow, origin allowed - response.setHeader("access-control-allow-origin", request.headers.origin); - response.setHeader("access-control-allow-methods", "GET, POST, OPTIONS"); - response.setHeader("access-control-allow-headers", "content-type, accept"); + response.setHeader( + "access-control-allow-origin", + request.headers.origin, + ); + response.setHeader( + "access-control-allow-methods", + "GET, POST, OPTIONS", + ); + response.setHeader( + "access-control-allow-headers", + "content-type, accept", + ); response.setHeader("access-control-max-age", "60"); return true; } else { @@ -336,19 +354,21 @@ exports.createWebServer = function(options) { return true; } - //Handle OPTIONS method (CORS) /////////////////////////////////////////////////// function processOptions(request, response) { if (VerifyCORSAndSetHeaders(request, response)) { - response.writeHead("204", "No Content", {"content-length": 0}); + response.writeHead("204", "No Content", { "content-length": 0 }); } else { - response.writeHead("403", "Origin " + request.headers.origin + " not allowed", {}); + response.writeHead( + "403", + "Origin " + request.headers.origin + " not allowed", + {}, + ); } response.end(); } - //Handle POST methods (TXHRTransport) /////////////////////////////////////////////////// function processPost(request, response) { @@ -363,39 +383,47 @@ exports.createWebServer = function(options) { //Verify CORS requirements if (!VerifyCORSAndSetHeaders(request, response)) { - response.writeHead("403", "Origin " + request.headers.origin + " not allowed", {}); + response.writeHead( + "403", + "Origin " + request.headers.origin + " not allowed", + {}, + ); response.end(); return; } //Process XHR payload - request.on('data', svc.transport.receiver(function(transportWithData) { - var input = new svc.protocol(transportWithData); - var output = new svc.protocol(new svc.transport(undefined, function(buf) { + request.on( + "data", + svc.transport.receiver(function (transportWithData) { + var input = new svc.protocol(transportWithData); + var output = new svc.protocol( + new svc.transport(undefined, function (buf) { + try { + response.writeHead(200); + response.end(buf); + } catch (err) { + response.writeHead(500); + response.end(); + } + }), + ); + try { - response.writeHead(200); - response.end(buf); + svc.processor.process(input, output); + transportWithData.commitPosition(); } catch (err) { - response.writeHead(500); - response.end(); - } - })); - - try { - svc.processor.process(input, output); - transportWithData.commitPosition(); - } catch (err) { - if (err instanceof InputBufferUnderrunError) { - transportWithData.rollbackPosition(); - } else { - response.writeHead(500); - response.end(); + if (err instanceof InputBufferUnderrunError) { + transportWithData.rollbackPosition(); + } else { + response.writeHead(500); + response.end(); + } } - } - })); + }), + ); } - //Handle GET methods (Static Page Server) /////////////////////////////////////////////////// function processGet(request, response) { @@ -408,7 +436,11 @@ exports.createWebServer = function(options) { //Verify CORS requirements if (!VerifyCORSAndSetHeaders(request, response)) { - response.writeHead("403", "Origin " + request.headers.origin + " not allowed", {}); + response.writeHead( + "403", + "Origin " + request.headers.origin + " not allowed", + {}, + ); response.end(); return; } @@ -424,18 +456,18 @@ exports.createWebServer = function(options) { return; } - fs.exists(filename, function(exists) { - if(!exists) { + fs.exists(filename, function (exists) { + if (!exists) { response.writeHead(404); response.end(); return; } if (fs.statSync(filename).isDirectory()) { - filename += '/index.html'; + filename += "/index.html"; } - fs.readFile(filename, "binary", function(err, file) { + fs.readFile(filename, "binary", function (err, file) { if (err) { response.writeHead(500); response.end(err + "\n"); @@ -456,30 +488,29 @@ exports.createWebServer = function(options) { }); } - //Handle WebSocket calls (TWebSocketTransport) /////////////////////////////////////////////////// function processWS(data, socket, svc, binEncoding) { - svc.transport.receiver(function(transportWithData) { + svc.transport.receiver(function (transportWithData) { var input = new svc.protocol(transportWithData); - var output = new svc.protocol(new svc.transport(undefined, function(buf) { - try { - var frame = wsFrame.encode(buf, null, binEncoding); - socket.write(frame); - } catch (err) { - //TODO: Add better error processing - } - })); + var output = new svc.protocol( + new svc.transport(undefined, function (buf) { + try { + var frame = wsFrame.encode(buf, null, binEncoding); + socket.write(frame); + } catch (err) { + //TODO: Add better error processing + } + }), + ); try { svc.processor.process(input, output); transportWithData.commitPosition(); - } - catch (err) { + } catch (err) { if (err instanceof InputBufferUnderrunError) { transportWithData.rollbackPosition(); - } - else { + } else { //TODO: Add better error processing } } @@ -498,69 +529,83 @@ exports.createWebServer = function(options) { // - GET static files, // - POST XHR Thrift services // - OPTIONS CORS requests - server.on('request', function(request, response) { - if (request.method === 'POST') { - processPost(request, response); - } else if (request.method === 'GET') { - processGet(request, response); - } else if (request.method === 'OPTIONS') { - processOptions(request, response); - } else { - response.writeHead(500); - response.end(); - } - }).on('upgrade', function(request, socket, head) { - //Lookup service - var svc; - try { - svc = services[Object.keys(services)[0]]; - } catch(e) { - socket.write("HTTP/1.1 403 No Apache Thrift Service available\r\n\r\n"); - return; - } - //Perform upgrade - var hash = crypto.createHash("sha1"); - hash.update(request.headers['sec-websocket-key'] + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"); - socket.write("HTTP/1.1 101 Switching Protocols\r\n" + - "Upgrade: websocket\r\n" + - "Connection: Upgrade\r\n" + - "Sec-WebSocket-Accept: " + hash.digest("base64") + "\r\n" + - "Sec-WebSocket-Origin: " + request.headers.origin + "\r\n" + - "Sec-WebSocket-Location: ws://" + request.headers.host + request.url + "\r\n" + - "\r\n"); - //Handle WebSocket traffic - var data = null; - socket.on('data', function(frame) { + server + .on("request", function (request, response) { + if (request.method === "POST") { + processPost(request, response); + } else if (request.method === "GET") { + processGet(request, response); + } else if (request.method === "OPTIONS") { + processOptions(request, response); + } else { + response.writeHead(500); + response.end(); + } + }) + .on("upgrade", function (request, socket, head) { + //Lookup service + var svc; try { - while (frame) { - var result = wsFrame.decode(frame); - //Prepend any existing decoded data - if (data) { - if (result.data) { - var newData = new Buffer(data.length + result.data.length); - data.copy(newData); - result.data.copy(newData, data.length); - result.data = newData; + svc = services[Object.keys(services)[0]]; + } catch (e) { + socket.write("HTTP/1.1 403 No Apache Thrift Service available\r\n\r\n"); + return; + } + //Perform upgrade + var hash = crypto.createHash("sha1"); + hash.update( + request.headers["sec-websocket-key"] + + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11", + ); + socket.write( + "HTTP/1.1 101 Switching Protocols\r\n" + + "Upgrade: websocket\r\n" + + "Connection: Upgrade\r\n" + + "Sec-WebSocket-Accept: " + + hash.digest("base64") + + "\r\n" + + "Sec-WebSocket-Origin: " + + request.headers.origin + + "\r\n" + + "Sec-WebSocket-Location: ws://" + + request.headers.host + + request.url + + "\r\n" + + "\r\n", + ); + //Handle WebSocket traffic + var data = null; + socket.on("data", function (frame) { + try { + while (frame) { + var result = wsFrame.decode(frame); + //Prepend any existing decoded data + if (data) { + if (result.data) { + var newData = new Buffer(data.length + result.data.length); + data.copy(newData); + result.data.copy(newData, data.length); + result.data = newData; + } else { + result.data = data; + } + data = null; + } + //If this completes a message process it + if (result.FIN) { + processWS(result.data, socket, svc, result.binEncoding); } else { - result.data = data; + data = result.data; } - data = null; + //Prepare next frame for decoding (if any) + frame = result.nextFrame; } - //If this completes a message process it - if (result.FIN) { - processWS(result.data, socket, svc, result.binEncoding); - } else { - data = result.data; - } - //Prepare next frame for decoding (if any) - frame = result.nextFrame; + } catch (e) { + log.error("TWebSocketTransport Exception: " + e); + socket.destroy(); } - } catch(e) { - log.error('TWebSocketTransport Exception: ' + e); - socket.destroy(); - } + }); }); - }); //Return the server return server; diff --git a/lib/nodejs/lib/thrift/ws_connection.js b/lib/nodejs/lib/thrift/ws_connection.js index 8ee8f6eca18..878a5724ff3 100644 --- a/lib/nodejs/lib/thrift/ws_connection.js +++ b/lib/nodejs/lib/thrift/ws_connection.js @@ -16,17 +16,17 @@ * specific language governing permissions and limitations * under the License. */ -var util = require('util'); -var WebSocket = require('isomorphic-ws'); +var util = require("util"); +var WebSocket = require("isomorphic-ws"); var EventEmitter = require("events").EventEmitter; -var thrift = require('./thrift'); +var thrift = require("./thrift"); -var TBufferedTransport = require('./buffered_transport'); -var TJSONProtocol = require('./json_protocol'); -var InputBufferUnderrunError = require('./input_buffer_underrun_error'); +var TBufferedTransport = require("./buffered_transport"); +var TJSONProtocol = require("./json_protocol"); +var InputBufferUnderrunError = require("./input_buffer_underrun_error"); -var createClient = require('./create_client'); -var jsEnv = require('browser-or-node'); +var createClient = require("./create_client"); +var jsEnv = require("browser-or-node"); exports.WSConnection = WSConnection; /** @@ -95,38 +95,38 @@ function WSConnection(host, port, options) { this.wsOptions = { host: this.host, port: this.port || 80, - path: this.options.path || '/', - headers: this.options.headers || {} + path: this.options.path || "/", + headers: this.options.headers || {}, }; for (var attrname in this.options.wsOptions) { this.wsOptions[attrname] = this.options.wsOptions[attrname]; } -}; +} util.inherits(WSConnection, EventEmitter); -WSConnection.prototype.__reset = function() { +WSConnection.prototype.__reset = function () { this.socket = null; //The web socket this.send_pending = []; //Buffers/Callback pairs waiting to be sent }; -WSConnection.prototype.__onOpen = function() { +WSConnection.prototype.__onOpen = function () { this.emit("open"); if (this.send_pending.length > 0) { //If the user made calls before the connection was fully //open, send them now - this.send_pending.forEach(function(data) { + this.send_pending.forEach(function (data) { this.socket.send(data); }, this); this.send_pending = []; } }; -WSConnection.prototype.__onClose = function(evt) { +WSConnection.prototype.__onClose = function (evt) { this.emit("close"); this.__reset(); }; -WSConnection.prototype.__decodeCallback = function(transport_with_data) { +WSConnection.prototype.__decodeCallback = function (transport_with_data) { var proto = new this.protocol(transport_with_data); try { while (true) { @@ -151,7 +151,7 @@ WSConnection.prototype.__decodeCallback = function(transport_with_data) { delete this.seqId2Service[header.rseqid]; } /*jshint -W083 */ - client._reqs[dummy_seqid] = function(err, success) { + client._reqs[dummy_seqid] = function (err, success) { transport_with_data.commitPosition(); var clientCallback = client._reqs[header.rseqid]; delete client._reqs[header.rseqid]; @@ -160,14 +160,17 @@ WSConnection.prototype.__decodeCallback = function(transport_with_data) { } }; /*jshint +W083 */ - if (client['recv_' + header.fname]) { - client['recv_' + header.fname](proto, header.mtype, dummy_seqid); + if (client["recv_" + header.fname]) { + client["recv_" + header.fname](proto, header.mtype, dummy_seqid); } else { delete client._reqs[dummy_seqid]; - this.emit("error", + this.emit( + "error", new thrift.TApplicationException( thrift.TApplicationExceptionType.WRONG_METHOD_NAME, - "Received a response to an unknown RPC function")); + "Received a response to an unknown RPC function", + ), + ); } } } catch (e) { @@ -179,20 +182,19 @@ WSConnection.prototype.__decodeCallback = function(transport_with_data) { } }; -WSConnection.prototype.__onData = function(data) { +WSConnection.prototype.__onData = function (data) { if (Object.prototype.toString.call(data) === "[object ArrayBuffer]") { data = new Uint8Array(data); } var buf = new Buffer(data); this.transport.receiver(this.__decodeCallback.bind(this))(buf); - }; -WSConnection.prototype.__onMessage = function(evt) { +WSConnection.prototype.__onMessage = function (evt) { this.__onData(evt.data); }; -WSConnection.prototype.__onError = function(evt) { +WSConnection.prototype.__onError = function (evt) { this.emit("error", evt); this.socket.close(); }; @@ -202,14 +204,14 @@ WSConnection.prototype.__onError = function(evt) { * @readonly * @returns {boolean} */ -WSConnection.prototype.isOpen = function() { +WSConnection.prototype.isOpen = function () { return this.socket && this.socket.readyState === this.socket.OPEN; }; /** * Opens the transport connection */ -WSConnection.prototype.open = function() { +WSConnection.prototype.open = function () { //If OPEN/CONNECTING/CLOSING ignore additional opens if (this.socket && this.socket.readyState !== this.socket.CLOSED) { return; @@ -220,7 +222,7 @@ WSConnection.prototype.open = function() { } else { this.socket = new WebSocket(this.uri(), "", this.wsOptions); } - this.socket.binaryType = 'arraybuffer'; + this.socket.binaryType = "arraybuffer"; this.socket.onopen = this.__onOpen.bind(this); this.socket.onmessage = this.__onMessage.bind(this); this.socket.onerror = this.__onError.bind(this); @@ -230,7 +232,7 @@ WSConnection.prototype.open = function() { /** * Closes the transport connection */ -WSConnection.prototype.close = function() { +WSConnection.prototype.close = function () { this.socket.close(); }; @@ -238,19 +240,22 @@ WSConnection.prototype.close = function() { * Return URI for the connection * @returns {string} URI */ -WSConnection.prototype.uri = function() { - var schema = this.secure ? 'wss' : 'ws'; - var port = ''; - var path = this.path || '/'; +WSConnection.prototype.uri = function () { + var schema = this.secure ? "wss" : "ws"; + var port = ""; + var path = this.path || "/"; var host = this.host; // avoid port if default for schema - if (this.port && (('wss' === schema && this.port !== 443) || - ('ws' === schema && this.port !== 80))) { - port = ':' + this.port; + if ( + this.port && + (("wss" === schema && this.port !== 443) || + ("ws" === schema && this.port !== 80)) + ) { + port = ":" + this.port; } - return schema + '://' + host + port + path; + return schema + "://" + host + port + path; }; /** @@ -260,7 +265,7 @@ WSConnection.prototype.uri = function() { * @event {error} the "error" event is raised upon request failure passing the * Node.js error object to the listener. */ -WSConnection.prototype.write = function(data) { +WSConnection.prototype.write = function (data) { if (this.isOpen()) { //Send data and register a callback to invoke the client callback this.socket.send(data); @@ -279,7 +284,7 @@ WSConnection.prototype.write = function(data) { * @returns {WSConnection} The connection object. * @see {@link WSConnectOptions} */ -exports.createWSConnection = function(host, port, options) { +exports.createWSConnection = function (host, port, options) { return new WSConnection(host, port, options); }; diff --git a/lib/nodejs/lib/thrift/ws_transport.js b/lib/nodejs/lib/thrift/ws_transport.js index 4cf62b9f9bf..94b6d90221b 100644 --- a/lib/nodejs/lib/thrift/ws_transport.js +++ b/lib/nodejs/lib/thrift/ws_transport.js @@ -17,7 +17,7 @@ * under the License. */ -var log = require('./log'); +var log = require("./log"); module.exports = TWebSocketTransport; @@ -33,19 +33,18 @@ module.exports = TWebSocketTransport; * var transport = new Thrift.TWebSocketTransport("http://localhost:8585"); */ function TWebSocketTransport(url) { - this.__reset(url); -}; - - -TWebSocketTransport.prototype.__reset = function(url) { - this.url = url; //Where to connect - this.socket = null; //The web socket - this.callbacks = []; //Pending callbacks - this.send_pending = []; //Buffers/Callback pairs waiting to be sent - this.send_buf = ''; //Outbound data, immutable until sent - this.recv_buf = ''; //Inbound data - this.rb_wpos = 0; //Network write position in receive buffer - this.rb_rpos = 0; //Client read position in receive buffer + this.__reset(url); +} + +TWebSocketTransport.prototype.__reset = function (url) { + this.url = url; //Where to connect + this.socket = null; //The web socket + this.callbacks = []; //Pending callbacks + this.send_pending = []; //Buffers/Callback pairs waiting to be sent + this.send_buf = ""; //Outbound data, immutable until sent + this.recv_buf = ""; //Inbound data + this.rb_wpos = 0; //Network write position in receive buffer + this.rb_rpos = 0; //Client read position in receive buffer }; /** @@ -56,58 +55,62 @@ TWebSocketTransport.prototype.__reset = function(url) { * @param {object} callback - The client completion callback. * @returns {undefined|string} Nothing (undefined) */ -TWebSocketTransport.prototype.flush = function(async, callback) { +TWebSocketTransport.prototype.flush = function (async, callback) { var self = this; if (this.isOpen()) { //Send data and register a callback to invoke the client callback this.socket.send(this.send_buf); - this.callbacks.push((function() { - var clientCallback = callback; - return function(msg) { - self.setRecvBuffer(msg); - clientCallback(); - }; - }())); + this.callbacks.push( + (function () { + var clientCallback = callback; + return function (msg) { + self.setRecvBuffer(msg); + clientCallback(); + }; + })(), + ); } else { //Queue the send to go out __onOpen this.send_pending.push({ buf: this.send_buf, - cb: callback + cb: callback, }); } }; -TWebSocketTransport.prototype.__onOpen = function() { - var self = this; - if (this.send_pending.length > 0) { - //If the user made calls before the connection was fully - //open, send them now - this.send_pending.forEach(function(elem) { - self.socket.send(elem.buf); - self.callbacks.push((function() { - var clientCallback = elem.cb; - return function(msg) { - self.setRecvBuffer(msg); - clientCallback(); - }; - }())); - }); - this.send_pending = []; - } +TWebSocketTransport.prototype.__onOpen = function () { + var self = this; + if (this.send_pending.length > 0) { + //If the user made calls before the connection was fully + //open, send them now + this.send_pending.forEach(function (elem) { + self.socket.send(elem.buf); + self.callbacks.push( + (function () { + var clientCallback = elem.cb; + return function (msg) { + self.setRecvBuffer(msg); + clientCallback(); + }; + })(), + ); + }); + this.send_pending = []; + } }; -TWebSocketTransport.prototype.__onClose = function(evt) { +TWebSocketTransport.prototype.__onClose = function (evt) { this.__reset(this.url); }; -TWebSocketTransport.prototype.__onMessage = function(evt) { +TWebSocketTransport.prototype.__onMessage = function (evt) { if (this.callbacks.length) { this.callbacks.shift()(evt.data); } }; -TWebSocketTransport.prototype.__onError = function(evt) { - log.error('websocket: ' + evt.toString()); +TWebSocketTransport.prototype.__onError = function (evt) { + log.error("websocket: " + evt.toString()); this.socket.close(); }; @@ -115,7 +118,7 @@ TWebSocketTransport.prototype.__onError = function(evt) { * Sets the buffer to use when receiving server responses. * @param {string} buf - The buffer to receive server responses. */ -TWebSocketTransport.prototype.setRecvBuffer = function(buf) { +TWebSocketTransport.prototype.setRecvBuffer = function (buf) { this.recv_buf = buf; this.recv_buf_sz = this.recv_buf.length; this.wpos = this.recv_buf.length; @@ -127,14 +130,14 @@ TWebSocketTransport.prototype.setRecvBuffer = function(buf) { * @readonly * @returns {boolean} */ -TWebSocketTransport.prototype.isOpen = function() { +TWebSocketTransport.prototype.isOpen = function () { return this.socket && this.socket.readyState == this.socket.OPEN; }; /** * Opens the transport connection */ -TWebSocketTransport.prototype.open = function() { +TWebSocketTransport.prototype.open = function () { //If OPEN/CONNECTING/CLOSING ignore additional opens if (this.socket && this.socket.readyState != this.socket.CLOSED) { return; @@ -150,7 +153,7 @@ TWebSocketTransport.prototype.open = function() { /** * Closes the transport connection */ -TWebSocketTransport.prototype.close = function() { +TWebSocketTransport.prototype.close = function () { this.socket.close(); }; @@ -160,11 +163,11 @@ TWebSocketTransport.prototype.close = function() { * @param {number} len - The number of characters to return. * @returns {string} Characters sent by the server. */ -TWebSocketTransport.prototype.read = function(len) { +TWebSocketTransport.prototype.read = function (len) { var avail = this.wpos - this.rpos; if (avail === 0) { - return ''; + return ""; } var give = len; @@ -184,7 +187,7 @@ TWebSocketTransport.prototype.read = function(len) { * Returns the entire response buffer. * @returns {string} Characters sent by the server. */ -TWebSocketTransport.prototype.readAll = function() { +TWebSocketTransport.prototype.readAll = function () { return this.recv_buf; }; @@ -192,7 +195,7 @@ TWebSocketTransport.prototype.readAll = function() { * Sets the send buffer to buf. * @param {string} buf - The buffer to send. */ -TWebSocketTransport.prototype.write = function(buf) { +TWebSocketTransport.prototype.write = function (buf) { this.send_buf = buf; }; @@ -201,6 +204,6 @@ TWebSocketTransport.prototype.write = function(buf) { * @readonly * @returns {string} The send buffer. */ -TWebSocketTransport.prototype.getSendBuffer = function() { +TWebSocketTransport.prototype.getSendBuffer = function () { return this.send_buf; }; diff --git a/lib/nodejs/lib/thrift/xhr_connection.js b/lib/nodejs/lib/thrift/xhr_connection.js index 6459c900c2a..ea542d1fe58 100644 --- a/lib/nodejs/lib/thrift/xhr_connection.js +++ b/lib/nodejs/lib/thrift/xhr_connection.js @@ -16,15 +16,15 @@ * specific language governing permissions and limitations * under the License. */ -var util = require('util'); +var util = require("util"); var EventEmitter = require("events").EventEmitter; -var thrift = require('./thrift'); +var thrift = require("./thrift"); -var TBufferedTransport = require('./buffered_transport'); -var TJSONProtocol = require('./json_protocol'); -var InputBufferUnderrunError = require('./input_buffer_underrun_error'); +var TBufferedTransport = require("./buffered_transport"); +var TJSONProtocol = require("./json_protocol"); +var InputBufferUnderrunError = require("./input_buffer_underrun_error"); -var createClient = require('./create_client'); +var createClient = require("./create_client"); exports.XHRConnection = XHRConnection; @@ -43,43 +43,49 @@ function XHRConnection(host, port, options) { this.options = options || {}; this.wpos = 0; this.rpos = 0; - this.useCORS = (options && options.useCORS); - this.send_buf = ''; - this.recv_buf = ''; + this.useCORS = options && options.useCORS; + this.send_buf = ""; + this.recv_buf = ""; this.transport = options.transport || TBufferedTransport; this.protocol = options.protocol || TJSONProtocol; this.headers = options.headers || {}; host = host || window.location.host; port = port || window.location.port; - var prefix = options.https ? 'https://' : 'http://'; - var path = options.path || '/'; + var prefix = options.https ? "https://" : "http://"; + var path = options.path || "/"; - if (port === '') { + if (port === "") { port = undefined; } - if (!port || port === 80 || port === '80') { + if (!port || port === 80 || port === "80") { this.url = prefix + host + path; } else { - this.url = prefix + host + ':' + port + path; + this.url = prefix + host + ":" + port + path; } //The sequence map is used to map seqIDs back to the // calling client in multiplexed scenarios this.seqId2Service = {}; -}; +} util.inherits(XHRConnection, EventEmitter); /** -* Gets the browser specific XmlHttpRequest Object. -* @returns {object} the browser XHR interface object -*/ -XHRConnection.prototype.getXmlHttpRequestObject = function() { - try { return new XMLHttpRequest(); } catch (e1) { } - try { return new ActiveXObject('Msxml2.XMLHTTP'); } catch (e2) { } - try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch (e3) { } + * Gets the browser specific XmlHttpRequest Object. + * @returns {object} the browser XHR interface object + */ +XHRConnection.prototype.getXmlHttpRequestObject = function () { + try { + return new XMLHttpRequest(); + } catch (e1) {} + try { + return new ActiveXObject("Msxml2.XMLHTTP"); + } catch (e2) {} + try { + return new ActiveXObject("Microsoft.XMLHTTP"); + } catch (e3) {} throw "Your browser doesn't support XHR."; }; @@ -94,27 +100,27 @@ XHRConnection.prototype.getXmlHttpRequestObject = function() { * @returns {undefined|string} Nothing or the current send buffer. * @throws {string} If XHR fails. */ -XHRConnection.prototype.flush = function() { +XHRConnection.prototype.flush = function () { var self = this; - if (this.url === undefined || this.url === '') { + if (this.url === undefined || this.url === "") { return this.send_buf; } var xreq = this.getXmlHttpRequestObject(); if (xreq.overrideMimeType) { - xreq.overrideMimeType('application/json'); + xreq.overrideMimeType("application/json"); } - xreq.onreadystatechange = function() { + xreq.onreadystatechange = function () { if (this.readyState == 4 && this.status == 200) { self.setRecvBuffer(this.responseText); } }; - xreq.open('POST', this.url, true); + xreq.open("POST", this.url, true); - Object.keys(this.headers).forEach(function(headerKey) { + Object.keys(this.headers).forEach(function (headerKey) { xreq.setRequestHeader(headerKey, self.headers[headerKey]); }); @@ -125,7 +131,7 @@ XHRConnection.prototype.flush = function() { * Sets the buffer to provide the protocol when deserializing. * @param {string} buf - The buffer to supply the protocol. */ -XHRConnection.prototype.setRecvBuffer = function(buf) { +XHRConnection.prototype.setRecvBuffer = function (buf) { this.recv_buf = buf; this.recv_buf_sz = this.recv_buf.length; this.wpos = this.recv_buf.length; @@ -137,10 +143,9 @@ XHRConnection.prototype.setRecvBuffer = function(buf) { var thing = new Buffer(data || buf); this.transport.receiver(this.__decodeCallback.bind(this))(thing); - }; -XHRConnection.prototype.__decodeCallback = function(transport_with_data) { +XHRConnection.prototype.__decodeCallback = function (transport_with_data) { var proto = new this.protocol(transport_with_data); try { while (true) { @@ -165,7 +170,7 @@ XHRConnection.prototype.__decodeCallback = function(transport_with_data) { delete this.seqId2Service[header.rseqid]; } /*jshint -W083 */ - client._reqs[dummy_seqid] = function(err, success) { + client._reqs[dummy_seqid] = function (err, success) { transport_with_data.commitPosition(); var clientCallback = client._reqs[header.rseqid]; delete client._reqs[header.rseqid]; @@ -174,14 +179,17 @@ XHRConnection.prototype.__decodeCallback = function(transport_with_data) { } }; /*jshint +W083 */ - if (client['recv_' + header.fname]) { - client['recv_' + header.fname](proto, header.mtype, dummy_seqid); + if (client["recv_" + header.fname]) { + client["recv_" + header.fname](proto, header.mtype, dummy_seqid); } else { delete client._reqs[dummy_seqid]; - this.emit("error", + this.emit( + "error", new thrift.TApplicationException( thrift.TApplicationExceptionType.WRONG_METHOD_NAME, - "Received a response to an unknown RPC function")); + "Received a response to an unknown RPC function", + ), + ); } } } catch (e) { @@ -198,19 +206,19 @@ XHRConnection.prototype.__decodeCallback = function(transport_with_data) { * @readonly * @returns {boolean} Always True. */ -XHRConnection.prototype.isOpen = function() { +XHRConnection.prototype.isOpen = function () { return true; }; /** * Opens the transport connection, with XHR this is a nop. */ -XHRConnection.prototype.open = function() {}; +XHRConnection.prototype.open = function () {}; /** * Closes the transport connection, with XHR this is a nop. */ -XHRConnection.prototype.close = function() {}; +XHRConnection.prototype.close = function () {}; /** * Returns the specified number of characters from the response @@ -218,11 +226,11 @@ XHRConnection.prototype.close = function() {}; * @param {number} len - The number of characters to return. * @returns {string} Characters sent by the server. */ -XHRConnection.prototype.read = function(len) { +XHRConnection.prototype.read = function (len) { var avail = this.wpos - this.rpos; if (avail === 0) { - return ''; + return ""; } var give = len; @@ -242,7 +250,7 @@ XHRConnection.prototype.read = function(len) { * Returns the entire response buffer. * @returns {string} Characters sent by the server. */ -XHRConnection.prototype.readAll = function() { +XHRConnection.prototype.readAll = function () { return this.recv_buf; }; @@ -250,7 +258,7 @@ XHRConnection.prototype.readAll = function() { * Sets the send buffer to buf. * @param {string} buf - The buffer to send. */ -XHRConnection.prototype.write = function(buf) { +XHRConnection.prototype.write = function (buf) { this.send_buf = buf; this.flush(); }; @@ -260,7 +268,7 @@ XHRConnection.prototype.write = function(buf) { * @readonly * @returns {string} The send buffer. */ -XHRConnection.prototype.getSendBuffer = function() { +XHRConnection.prototype.getSendBuffer = function () { return this.send_buf; }; @@ -273,7 +281,7 @@ XHRConnection.prototype.getSendBuffer = function() { * @returns {XHRConnection} The connection object. * @see {@link XHRConnectOptions} */ -exports.createXHRConnection = function(host, port, options) { +exports.createXHRConnection = function (host, port, options) { return new XHRConnection(host, port, options); }; diff --git a/lib/nodejs/test/binary.test.js b/lib/nodejs/test/binary.test.js index 187cd187434..1e749d8e3d5 100644 --- a/lib/nodejs/test/binary.test.js +++ b/lib/nodejs/test/binary.test.js @@ -18,10 +18,10 @@ */ const test = require("tape"); -const binary = require("thrift/binary"); +const binary = require("thrift/lib/nodejs/lib/thrift/binary"); const cases = { - "Should read signed byte": function(assert) { + "Should read signed byte": function (assert) { assert.equal(1, binary.readByte(0x01)); assert.equal(-1, binary.readByte(0xff)); @@ -29,12 +29,12 @@ const cases = { assert.equal(-128, binary.readByte(0x80)); assert.end(); }, - "Should write byte": function(assert) { + "Should write byte": function (assert) { //Protocol simply writes to the buffer. Nothing to test.. yet. assert.ok(true); assert.end(); }, - "Should read I16": function(assert) { + "Should read I16": function (assert) { assert.equal(0, binary.readI16([0x00, 0x00])); assert.equal(1, binary.readI16([0x00, 0x01])); assert.equal(-1, binary.readI16([0xff, 0xff])); @@ -46,7 +46,7 @@ const cases = { assert.end(); }, - "Should write I16": function(assert) { + "Should write I16": function (assert) { assert.deepEqual([0x00, 0x00], binary.writeI16([], 0)); assert.deepEqual([0x00, 0x01], binary.writeI16([], 1)); assert.deepEqual([0xff, 0xff], binary.writeI16([], -1)); @@ -58,7 +58,7 @@ const cases = { assert.end(); }, - "Should read I32": function(assert) { + "Should read I32": function (assert) { assert.equal(0, binary.readI32([0x00, 0x00, 0x00, 0x00])); assert.equal(1, binary.readI32([0x00, 0x00, 0x00, 0x01])); assert.equal(-1, binary.readI32([0xff, 0xff, 0xff, 0xff])); @@ -70,7 +70,7 @@ const cases = { assert.end(); }, - "Should write I32": function(assert) { + "Should write I32": function (assert) { assert.deepEqual([0x00, 0x00, 0x00, 0x00], binary.writeI32([], 0)); assert.deepEqual([0x00, 0x00, 0x00, 0x01], binary.writeI32([], 1)); assert.deepEqual([0xff, 0xff, 0xff, 0xff], binary.writeI32([], -1)); @@ -78,137 +78,139 @@ const cases = { // Min I32 assert.deepEqual( [0x80, 0x00, 0x00, 0x00], - binary.writeI32([], -2147483648) + binary.writeI32([], -2147483648), ); // Max I32 assert.deepEqual([0x7f, 0xff, 0xff, 0xff], binary.writeI32([], 2147483647)); assert.end(); }, - "Should read doubles": function(assert) { + "Should read doubles": function (assert) { assert.equal( 0, - binary.readDouble([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]) + binary.readDouble([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]), ); assert.equal( 0, - binary.readDouble([0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]) + binary.readDouble([0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]), ); assert.equal( 1, - binary.readDouble([0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]) + binary.readDouble([0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]), ); assert.equal( 2, - binary.readDouble([0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]) + binary.readDouble([0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]), ); assert.equal( -2, - binary.readDouble([0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]) + binary.readDouble([0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]), ); assert.equal( Math.PI, - binary.readDouble([0x40, 0x9, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18]) + binary.readDouble([0x40, 0x9, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18]), ); assert.equal( Infinity, - binary.readDouble([0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]) + binary.readDouble([0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]), ); assert.equal( -Infinity, - binary.readDouble([0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]) + binary.readDouble([0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]), ); assert.ok( - isNaN(binary.readDouble([0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])) + isNaN( + binary.readDouble([0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]), + ), ); assert.equal( 1 / 3, - binary.readDouble([0x3f, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55]) + binary.readDouble([0x3f, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55]), ); // Min subnormal positive double assert.equal( 4.9406564584124654e-324, - binary.readDouble([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]) + binary.readDouble([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]), ); // Min normal positive double assert.equal( 2.2250738585072014e-308, - binary.readDouble([0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]) + binary.readDouble([0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]), ); // Max positive double assert.equal( 1.7976931348623157e308, - binary.readDouble([0x7f, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]) + binary.readDouble([0x7f, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]), ); assert.end(); }, - "Should write doubles": function(assert) { + "Should write doubles": function (assert) { assert.deepEqual( [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], - binary.writeDouble([], 0) + binary.writeDouble([], 0), ); assert.deepEqual( [0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], - binary.writeDouble([], 1) + binary.writeDouble([], 1), ); assert.deepEqual( [0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], - binary.writeDouble([], 2) + binary.writeDouble([], 2), ); assert.deepEqual( [0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], - binary.writeDouble([], -2) + binary.writeDouble([], -2), ); assert.deepEqual( [0x40, 0x9, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18], - binary.writeDouble([], Math.PI) + binary.writeDouble([], Math.PI), ); assert.deepEqual( [0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], - binary.writeDouble([], Infinity) + binary.writeDouble([], Infinity), ); assert.deepEqual( [0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], - binary.writeDouble([], -Infinity) + binary.writeDouble([], -Infinity), ); assert.deepEqual( [0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], - binary.writeDouble([], NaN) + binary.writeDouble([], NaN), ); assert.deepEqual( [0x3f, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55], - binary.writeDouble([], 1 / 3) + binary.writeDouble([], 1 / 3), ); // Min subnormal positive double assert.deepEqual( [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01], - binary.writeDouble([], 4.9406564584124654e-324) + binary.writeDouble([], 4.9406564584124654e-324), ); // Min normal positive double assert.deepEqual( [0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], - binary.writeDouble([], 2.2250738585072014e-308) + binary.writeDouble([], 2.2250738585072014e-308), ); // Max positive double assert.deepEqual( [0x7f, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff], - binary.writeDouble([], 1.7976931348623157e308) + binary.writeDouble([], 1.7976931348623157e308), ); assert.end(); - } + }, }; -Object.keys(cases).forEach(function(caseName) { +Object.keys(cases).forEach(function (caseName) { test(caseName, cases[caseName]); }); diff --git a/lib/nodejs/test/client.js b/lib/nodejs/test/client.mjs similarity index 71% rename from lib/nodejs/test/client.js rename to lib/nodejs/test/client.mjs index 31ea06e2f0d..6200dc6c428 100644 --- a/lib/nodejs/test/client.js +++ b/lib/nodejs/test/client.mjs @@ -19,64 +19,68 @@ * under the License. */ -const assert = require("assert"); -const thrift = require("thrift"); -const helpers = require("./helpers"); +import assert from "assert"; +import thrift from "thrift"; +import helpers from "./helpers.js"; -const ThriftTest = require(`./${helpers.genPath}/ThriftTest`); -const ThriftTestDriver = require("./test_driver").ThriftTestDriver; -const ThriftTestDriverPromise = require("./test_driver") - .ThriftTestDriverPromise; -const SecondService = require(`./${helpers.genPath}/SecondService`); +const ThriftTest = await import( + `./${helpers.genPath}/ThriftTest.${helpers.moduleExt}` +); +import { ThriftTestDriver, ThriftTestDriverPromise } from "./test_driver.mjs"; +const SecondService = await import( + `./${helpers.genPath}/SecondService.${helpers.moduleExt}` +); -const program = require("commander"); +import { program } from "commander"; program .option( "-p, --protocol ", - "Set thrift protocol (binary|compact|json) [protocol]" + "Set thrift protocol (binary|compact|json) [protocol]", ) .option( "-t, --transport ", - "Set thrift transport (buffered|framed|http) [transport]" + "Set thrift transport (buffered|framed|http) [transport]", ) .option("--port ", "Set thrift server port number to connect", 9090) .option("--host ", "Set thrift server host to connect", "localhost") .option( "--domain-socket ", - "Set thrift server unix domain socket to connect" + "Set thrift server unix domain socket to connect", ) .option("--ssl", "use SSL transport") .option("--callback", "test with callback style functions") .option( - "-t, --type ", + "--type ", "Select server type (http|multiplex|tcp|websocket)", - "tcp" + "tcp", ) .option("--es6", "Use es6 code") .option("--es5", "Use es5 code") + .option("--esm", "Use es modules") .parse(process.argv); -const host = program.host; -const port = program.port; -const domainSocket = program.domainSocket; -const ssl = program.ssl; -let type = program.type; +const opts = program.opts(); +const host = opts.host; +const port = opts.port; +const domainSocket = opts.domainSocket; +const ssl = opts.ssl; +let type = opts.type; /* for compatibility with cross test invocation for http transport testing */ -if (program.transport === "http") { - program.transport = "buffered"; +if (opts.transport === "http") { + opts.transport = "buffered"; type = "http"; } -if (program.transport === "websocket") { - program.transport = "buffered"; +if (opts.transport === "websocket") { + opts.transport = "buffered"; type = "websocket"; } const options = { - transport: helpers.transports[program.transport], - protocol: helpers.protocols[program.protocol] + transport: helpers.transports[opts.transport], + protocol: helpers.protocols[opts.protocol], }; if (type === "http" || type === "websocket") { @@ -101,10 +105,8 @@ if (ssl) { let connection; let client; -const testDriver = program.callback - ? ThriftTestDriver - : ThriftTestDriverPromise; -if (helpers.ecmaMode === "es6" && program.callback) { +const testDriver = opts.callback ? ThriftTestDriver : ThriftTestDriverPromise; +if (helpers.ecmaMode === "es6" && opts.callback) { console.log("ES6 does not support callback style"); process.exit(0); } @@ -128,7 +130,7 @@ if (type === "tcp" || type === "multiplex") { connection.open(); } -connection.on("error", function(err) { +connection.on("error", function (err) { assert(false, err); }); @@ -141,11 +143,11 @@ if (type === "tcp") { const secondclient = mp.createClient( "SecondService", SecondService, - connection + connection, ); - connection.on("connect", function() { - secondclient.secondtestString("Test", function(err, response) { + connection.on("connect", function () { + secondclient.secondtestString("Test", function (err, response) { assert(!err); assert.equal('testString("Test")', response); }); @@ -161,7 +163,7 @@ if (type === "tcp") { } function runTests() { - testDriver(client, function(status) { + testDriver(client, function (status) { console.log(status); if (type !== "http" && type !== "websocket") { connection.end(); @@ -172,4 +174,4 @@ function runTests() { }); } -exports.expressoTest = function() {}; +export const expressoTest = function () {}; diff --git a/lib/nodejs/test/deep-constructor.test.js b/lib/nodejs/test/deep-constructor.test.js index 504dacf0b3b..e5ac3f888e2 100644 --- a/lib/nodejs/test/deep-constructor.test.js +++ b/lib/nodejs/test/deep-constructor.test.js @@ -24,11 +24,11 @@ const bufferEquals = require("buffer-equals"); function serializeBinary(data) { let buff; - const transport = new thrift.TBufferedTransport(null, function(msg) { + const transport = new thrift.TBufferedTransport(null, function (msg) { buff = msg; }); const prot = new thrift.TBinaryProtocol(transport); - data.write(prot); + data[Symbol.for("write")](prot); prot.flush(); return buff; } @@ -37,18 +37,18 @@ function deserializeBinary(serialized, type) { const t = new thrift.TFramedTransport(serialized); const p = new thrift.TBinaryProtocol(t); const data = new type(); - data.read(p); + data[Symbol.for("read")](p); return data; } function serializeJSON(data) { let buff; - const transport = new thrift.TBufferedTransport(null, function(msg) { + const transport = new thrift.TBufferedTransport(null, function (msg) { buff = msg; }); const protocol = new thrift.TJSONProtocol(transport); protocol.writeMessageBegin("", 0, 0); - data.write(protocol); + data[Symbol.for("write")](protocol); protocol.writeMessageEnd(); protocol.flush(); return buff; @@ -59,7 +59,7 @@ function deserializeJSON(serialized, type) { const protocol = new thrift.TJSONProtocol(transport); protocol.readMessageBegin(); const data = new type(); - data.read(protocol); + data[Symbol.for("read")](protocol); protocol.readMessageEnd(); return data; } @@ -70,17 +70,17 @@ function createThriftObj() { struct_list_field: [ new ttypes.Simple({ value: "b" }), - new ttypes.Simple({ value: "c" }) + new ttypes.Simple({ value: "c" }), ], struct_set_field: [ new ttypes.Simple({ value: "d" }), - new ttypes.Simple({ value: "e" }) + new ttypes.Simple({ value: "e" }), ], struct_map_field: { A: new ttypes.Simple({ value: "f" }), - B: new ttypes.Simple({ value: "g" }) + B: new ttypes.Simple({ value: "g" }), }, struct_nested_containers_field: [ @@ -88,46 +88,46 @@ function createThriftObj() { { C: [ new ttypes.Simple({ value: "h" }), - new ttypes.Simple({ value: "i" }) - ] - } - ] + new ttypes.Simple({ value: "i" }), + ], + }, + ], ], struct_nested_containers_field2: { D: [ { - DA: new ttypes.Simple({ value: "j" }) + DA: new ttypes.Simple({ value: "j" }), }, { - DB: new ttypes.Simple({ value: "k" }) - } - ] + DB: new ttypes.Simple({ value: "k" }), + }, + ], }, list_of_list_field: [ ["l00", "l01", "l02"], ["l10", "l11", "l12"], - ["l20", "l21", "l22"] + ["l20", "l21", "l22"], ], list_of_list_of_list_field: [ [ ["m000", "m001", "m002"], ["m010", "m011", "m012"], - ["m020", "m021", "m022"] + ["m020", "m021", "m022"], ], [ ["m100", "m101", "m102"], ["m110", "m111", "m112"], - ["m120", "m121", "m122"] + ["m120", "m121", "m122"], ], [ ["m200", "m201", "m202"], ["m210", "m211", "m212"], - ["m220", "m221", "m222"] - ] - ] + ["m220", "m221", "m222"], + ], + ], }); } @@ -141,51 +141,51 @@ function createJsObj() { struct_map_field: { A: { value: "f" }, - B: { value: "g" } + B: { value: "g" }, }, struct_nested_containers_field: [ [ { - C: [{ value: "h" }, { value: "i" }] - } - ] + C: [{ value: "h" }, { value: "i" }], + }, + ], ], struct_nested_containers_field2: { D: [ { - DA: { value: "j" } + DA: { value: "j" }, }, { - DB: { value: "k" } - } - ] + DB: { value: "k" }, + }, + ], }, list_of_list_field: [ ["l00", "l01", "l02"], ["l10", "l11", "l12"], - ["l20", "l21", "l22"] + ["l20", "l21", "l22"], ], list_of_list_of_list_field: [ [ ["m000", "m001", "m002"], ["m010", "m011", "m012"], - ["m020", "m021", "m022"] + ["m020", "m021", "m022"], ], [ ["m100", "m101", "m102"], ["m110", "m111", "m112"], - ["m120", "m121", "m122"] + ["m120", "m121", "m122"], ], [ ["m200", "m201", "m202"], ["m210", "m211", "m212"], - ["m220", "m221", "m222"] - ] - ] + ["m220", "m221", "m222"], + ], + ], }; } @@ -244,7 +244,7 @@ function assertValues(obj, assert) { function createTestCases(serialize, deserialize) { const cases = { - "Serialize/deserialize should return equal object": function(assert) { + "Serialize/deserialize should return equal object": function (assert) { const tObj = createThriftObj(); const received = deserialize(serialize(tObj), ttypes.Complex); assert.ok(tObj !== received, "not the same object"); @@ -252,51 +252,49 @@ function createTestCases(serialize, deserialize) { assert.end(); }, - "Nested structs and containers initialized from plain js objects should serialize same as if initialized from thrift objects": function( - assert - ) { - const tObj1 = createThriftObj(); - const tObj2 = new ttypes.Complex(createJsObj()); - assertValues(tObj2, assert); - const s1 = serialize(tObj1); - const s2 = serialize(tObj2); - assert.ok(bufferEquals(s1, s2)); - assert.end(); - }, - - "Modifications to args object should not affect constructed Thrift object": function( - assert - ) { - const args = createJsObj(); - assertValues(args, assert); - - const tObj = new ttypes.Complex(args); - assertValues(tObj, assert); - - args.struct_field.value = "ZZZ"; - args.struct_list_field[0].value = "ZZZ"; - args.struct_list_field[1].value = "ZZZ"; - args.struct_set_field[0].value = "ZZZ"; - args.struct_set_field[1].value = "ZZZ"; - args.struct_map_field.A.value = "ZZZ"; - args.struct_map_field.B.value = "ZZZ"; - args.struct_nested_containers_field[0][0].C[0] = "ZZZ"; - args.struct_nested_containers_field[0][0].C[1] = "ZZZ"; - args.struct_nested_containers_field2.D[0].DA = "ZZZ"; - args.struct_nested_containers_field2.D[0].DB = "ZZZ"; - - assertValues(tObj, assert); - assert.end(); - }, - - "nulls are ok": function(assert) { + "Nested structs and containers initialized from plain js objects should serialize same as if initialized from thrift objects": + function (assert) { + const tObj1 = createThriftObj(); + const tObj2 = new ttypes.Complex(createJsObj()); + assertValues(tObj2, assert); + const s1 = serialize(tObj1); + const s2 = serialize(tObj2); + assert.ok(bufferEquals(s1, s2)); + assert.end(); + }, + + "Modifications to args object should not affect constructed Thrift object": + function (assert) { + const args = createJsObj(); + assertValues(args, assert); + + const tObj = new ttypes.Complex(args); + assertValues(tObj, assert); + + args.struct_field.value = "ZZZ"; + args.struct_list_field[0].value = "ZZZ"; + args.struct_list_field[1].value = "ZZZ"; + args.struct_set_field[0].value = "ZZZ"; + args.struct_set_field[1].value = "ZZZ"; + args.struct_map_field.A.value = "ZZZ"; + args.struct_map_field.B.value = "ZZZ"; + args.struct_nested_containers_field[0][0].C[0] = "ZZZ"; + args.struct_nested_containers_field[0][0].C[1] = "ZZZ"; + args.struct_nested_containers_field2.D[0].DA = "ZZZ"; + args.struct_nested_containers_field2.D[0].DB = "ZZZ"; + + assertValues(tObj, assert); + assert.end(); + }, + + "nulls are ok": function (assert) { const tObj = new ttypes.Complex({ struct_field: null, struct_list_field: null, struct_set_field: null, struct_map_field: null, struct_nested_containers_field: null, - struct_nested_containers_field2: null + struct_nested_containers_field2: null, }); const received = deserialize(serialize(tObj), ttypes.Complex); assert.strictEqual(tObj.struct_field, null); @@ -305,9 +303,9 @@ function createTestCases(serialize, deserialize) { assert.end(); }, - "Can make list with objects": function(assert) { + "Can make list with objects": function (assert) { const tObj = new ttypes.ComplexList({ - struct_list_field: [new ttypes.Complex({})] + struct_list_field: [new ttypes.Complex({})], }); const innerObj = tObj.struct_list_field[0]; assert.ok(innerObj instanceof ttypes.Complex); @@ -318,13 +316,13 @@ function createTestCases(serialize, deserialize) { assert.strictEqual(innerObj.struct_nested_containers_field, null); assert.strictEqual(innerObj.struct_nested_containers_field2, null); assert.end(); - } + }, }; return cases; } function run(name, cases) { - Object.keys(cases).forEach(function(caseName) { + Object.keys(cases).forEach(function (caseName) { test(name + ": " + caseName, cases[caseName]); }); } diff --git a/lib/nodejs/test/episodic-code-generation-test/client.js b/lib/nodejs/test/episodic-code-generation-test/client.js index 55dc70269ca..cf014c26354 100644 --- a/lib/nodejs/test/episodic-code-generation-test/client.js +++ b/lib/nodejs/test/episodic-code-generation-test/client.js @@ -22,7 +22,7 @@ const assert = require("assert"); const test = require("tape"); const thrift = require("thrift"); -const program = require("commander"); +const { program } = require("commander"); program .option("--host ", "Set the thrift server host to connect", "localhost") @@ -32,26 +32,27 @@ program const Service = require("./gen-2/second-episode/gen-nodejs/Service"); const Types = require("types-package/first-episode/Types_types"); -const host = program.host; -const port = program.port; +const opts = program.opts(); +const host = opts.host; +const port = opts.port; const options = { transport: thrift.TBufferedTransport, - protocol: thrift.TJSONProtocol + protocol: thrift.TJSONProtocol, }; const connection = thrift.createConnection(host, port, options); -const testDriver = function(client, callback) { - test("NodeJS episodic compilation client-server test", function(assert) { +const testDriver = function (client, callback) { + test("NodeJS episodic compilation client-server test", function (assert) { const type1Object = new Types.Type1(); type1Object.number = 42; type1Object.message = "The answer"; - client.testEpisode(type1Object, function(err, response) { + client.testEpisode(type1Object, function (err, response) { assert.error(err, "no callback error"); assert.equal(response.number, type1Object.number + 1); assert.equal( response.message, - type1Object.message + " [Hello from the server]" + type1Object.message + " [Hello from the server]", ); assert.end(); callback("Server successfully tested"); @@ -59,7 +60,7 @@ const testDriver = function(client, callback) { }); }; -connection.on("error", function(err) { +connection.on("error", function (err) { assert(false, err); }); @@ -68,10 +69,10 @@ const client = thrift.createClient(Service, connection); runTests(); function runTests() { - testDriver(client, function(status) { + testDriver(client, function (status) { console.log(status); connection.destroy(); }); } -exports.expressoTest = function() {}; +exports.expressoTest = function () {}; diff --git a/lib/nodejs/test/episodic-code-generation-test/server.js b/lib/nodejs/test/episodic-code-generation-test/server.js index 2917b681c84..2b9a96d0cac 100644 --- a/lib/nodejs/test/episodic-code-generation-test/server.js +++ b/lib/nodejs/test/episodic-code-generation-test/server.js @@ -20,7 +20,7 @@ */ const thrift = require("../../lib/thrift"); -const program = require("commander"); +const { program } = require("commander"); program .option("--port ", "Set the thrift server port", 9090) @@ -29,21 +29,22 @@ program const Service = require("./gen-2/second-episode/gen-nodejs/Service"); const Types = require("types-package/first-episode/Types_types"); -const port = program.port; +const opts = program.opts(); +const port = opts.port; const options = { transport: thrift.TBufferedTransport, - protocol: thrift.TJSONProtocol + protocol: thrift.TJSONProtocol, }; const ServiceHandler = { - testEpisode: function(receivedType1Object) { + testEpisode: function (receivedType1Object) { const type1Object = new Types.Type1(); type1Object.number = receivedType1Object.number + 1; type1Object.message = receivedType1Object.message + " [Hello from the server]"; return type1Object; - } + }, }; const server = thrift.createServer(Service, ServiceHandler, options); diff --git a/lib/nodejs/test/exceptions.js b/lib/nodejs/test/exceptions.js index ab2798a26a1..4119e76b052 100644 --- a/lib/nodejs/test/exceptions.js +++ b/lib/nodejs/test/exceptions.js @@ -20,29 +20,29 @@ "use strict"; const test = require("tape"); const thrift = require("../lib/thrift/thrift.js"); -const InputBufferUnderrunError = require("../lib/thrift/input_buffer_underrun_error"); +const { InputBufferUnderrunError } = require("../lib/thrift"); test("TApplicationException", function t(assert) { const e = new thrift.TApplicationException(1, "foo"); assert.ok( e instanceof thrift.TApplicationException, - "is instanceof TApplicationException" + "is instanceof TApplicationException", ); assert.ok(e instanceof thrift.TException, "is instanceof TException"); assert.ok(e instanceof Error, "is instanceof Error"); assert.equal(typeof e.stack, "string", "has stack trace"); assert.ok( /^TApplicationException: foo/.test(e.stack), - "Stack trace has correct error name and message" + "Stack trace has correct error name and message", ); assert.ok( e.stack.indexOf("test/exceptions.js:7:11") !== -1, - "stack trace starts on correct line and column" + "stack trace starts on correct line and column", ); assert.equal( e.name, "TApplicationException", - "has function name TApplicationException" + "has function name TApplicationException", ); assert.equal(e.message, "foo", 'has error message "foo"'); assert.equal(e.type, 1, "has type 1"); @@ -53,23 +53,23 @@ test("unexpected TApplicationException ", function t(assert) { const e = new thrift.TApplicationException(1, 100); assert.ok( e instanceof thrift.TApplicationException, - "is instanceof TApplicationException" + "is instanceof TApplicationException", ); assert.ok(e instanceof thrift.TException, "is instanceof TException"); assert.ok(e instanceof Error, "is instanceof Error"); assert.equal(typeof e.stack, "string", "has stack trace"); assert.ok( /^TApplicationException: 100/.test(e.stack), - "Stack trace has correct error name and message" + "Stack trace has correct error name and message", ); assert.ok( e.stack.indexOf("test/exceptions.js:7:11") !== -1, - "stack trace starts on correct line and column" + "stack trace starts on correct line and column", ); assert.equal( e.name, "TApplicationException", - "has function name TApplicationException" + "has function name TApplicationException", ); assert.equal(e.message, 100, "has error message 100"); assert.equal(e.type, 1, "has type 1"); @@ -83,11 +83,11 @@ test("TException", function t(assert) { assert.equal(typeof e.stack, "string", "has stack trace"); assert.ok( /^TException: foo/.test(e.stack), - "Stack trace has correct error name and message" + "Stack trace has correct error name and message", ); assert.ok( e.stack.indexOf("test/exceptions.js:21:11") !== -1, - "stack trace starts on correct line and column" + "stack trace starts on correct line and column", ); assert.equal(e.name, "TException", "has function name TException"); assert.equal(e.message, "foo", 'has error message "foo"'); @@ -98,22 +98,22 @@ test("TProtocolException", function t(assert) { const e = new thrift.TProtocolException(1, "foo"); assert.ok( e instanceof thrift.TProtocolException, - "is instanceof TProtocolException" + "is instanceof TProtocolException", ); assert.ok(e instanceof Error, "is instanceof Error"); assert.equal(typeof e.stack, "string", "has stack trace"); assert.ok( /^TProtocolException: foo/.test(e.stack), - "Stack trace has correct error name and message" + "Stack trace has correct error name and message", ); assert.ok( e.stack.indexOf("test/exceptions.js:33:11") !== -1, - "stack trace starts on correct line and column" + "stack trace starts on correct line and column", ); assert.equal( e.name, "TProtocolException", - "has function name TProtocolException" + "has function name TProtocolException", ); assert.equal(e.message, "foo", 'has error message "foo"'); assert.equal(e.type, 1, "has type 1"); @@ -124,22 +124,22 @@ test("InputBufferUnderrunError", function t(assert) { const e = new InputBufferUnderrunError("foo"); assert.ok( e instanceof InputBufferUnderrunError, - "is instanceof InputBufferUnderrunError" + "is instanceof InputBufferUnderrunError", ); assert.ok(e instanceof Error, "is instanceof Error"); assert.equal(typeof e.stack, "string", "has stack trace"); assert.ok( /^InputBufferUnderrunError: foo/.test(e.stack), - "Stack trace has correct error name and message" + "Stack trace has correct error name and message", ); assert.ok( e.stack.indexOf("test/exceptions.js:46:11") !== -1, - "stack trace starts on correct line and column" + "stack trace starts on correct line and column", ); assert.equal( e.name, "InputBufferUnderrunError", - "has function name InputBufferUnderrunError" + "has function name InputBufferUnderrunError", ); assert.equal(e.message, "foo", 'has error message "foo"'); assert.end(); diff --git a/lib/nodejs/test/header.test.js b/lib/nodejs/test/header.test.js index 99bb832bc3c..24f49beff27 100644 --- a/lib/nodejs/test/header.test.js +++ b/lib/nodejs/test/header.test.js @@ -26,11 +26,11 @@ const test = require("tape"); const path = require("path"); const headerPayload = fs.readFileSync( - path.join(__dirname, "test_header_payload") + path.join(__dirname, "test_header_payload"), ); const cases = { - "Should read headers from payload": function(assert) { + "Should read headers from payload": function (assert) { const transport = new TFramedTransport(); transport.inBuf = Buffer.from(headerPayload); @@ -39,7 +39,7 @@ const cases = { assert.equals(headers.Trace, "abcde"); assert.end(); }, - "Should read different headers from different payload": function(assert) { + "Should read different headers from different payload": function (assert) { const transport = new TFramedTransport(); const buf = Buffer.from(headerPayload); buf[24] = 115; // Change Parent to Parens @@ -52,7 +52,7 @@ const cases = { assert.equals(headers.Trace, "abcde"); assert.end(); }, - "Should read headers when reading message begin": function(assert) { + "Should read headers when reading message begin": function (assert) { const transport = new TFramedTransport(); transport.inBuf = Buffer.from(headerPayload); const protocol = new THeaderProtocol(transport); @@ -65,7 +65,7 @@ const cases = { assert.equals(result.mtype, thrift.Thrift.MessageType.CALL); assert.end(); }, - "Should be able to write headers": function(assert) { + "Should be able to write headers": function (assert) { const writeTransport = new TFramedTransport(); writeTransport.setProtocolId(THeaderTransport.SubprotocolId.BINARY); writeTransport.setWriteHeader("Hihihihi", "hohohoho"); @@ -84,7 +84,7 @@ const cases = { assert.equals(headers.a, "z"); assert.end(); }, - "Separate transports should have separate headers": function(assert) { + "Separate transports should have separate headers": function (assert) { const writeTransport = new TFramedTransport(); writeTransport.setProtocolId(THeaderTransport.SubprotocolId.BINARY); writeTransport.setWriteHeader("foo", "bar"); @@ -100,9 +100,21 @@ const cases = { assert.equals(otherHeaders.foo, undefined); assert.equals(otherHeaders.otherfoo, "baz"); assert.end(); - } + }, + "Should handle large messages without crashing": function (assert) { + const callback = function () {}; + const onData = TFramedTransport.receiver(callback); + + const largeChunkSize = 2 * 100 * 1024 * 1024; + const largeChunk = Buffer.alloc(largeChunkSize, "A"); + const sizeBuffer = new Buffer(4); + sizeBuffer.writeInt32BE(largeChunkSize + 4, 0); + onData(Buffer.concat([sizeBuffer, largeChunk])); + + assert.end(); + }, }; -Object.keys(cases).forEach(function(caseName) { +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 f3c27b3d1f1..1ece2f1dcb3 100644 --- a/lib/nodejs/test/helpers.js +++ b/lib/nodejs/test/helpers.js @@ -18,21 +18,50 @@ */ "use strict"; -const thrift = require("../lib/thrift"); +const thrift = require("thrift"); module.exports.transports = { buffered: thrift.TBufferedTransport, - framed: thrift.TFramedTransport + framed: thrift.TFramedTransport, }; module.exports.protocols = { json: thrift.TJSONProtocol, binary: thrift.TBinaryProtocol, compact: thrift.TCompactProtocol, - header: thrift.THeaderProtocol + header: thrift.THeaderProtocol, }; -module.exports.ecmaMode = process.argv.includes("--es6") ? "es6" : "es5"; -module.exports.genPath = process.argv.includes("--es6") - ? "gen-nodejs-es6" - : "gen-nodejs"; +const variant = (function () { + if (process.argv.includes("--es6")) { + return "es6"; + } else if (process.argv.includes("--esm")) { + return "esm"; + } else { + return "es5"; + } +})(); + +module.exports.ecmaMode = ["esm", "es6"].includes(variant) ? "es6" : "es5"; +const genPath = (module.exports.genPath = (function () { + if (variant == "es5") { + return "gen-nodejs"; + } else { + return `gen-nodejs-${variant}`; + } +})()); + +const moduleExt = (module.exports.moduleExt = variant === "esm" ? "mjs" : "js"); + +/** + * Imports a types module, correctly handling the differences in esm and commonjs + */ +module.exports.importTypes = async function (filename) { + const typesModule = await import(`./${genPath}/${filename}.${moduleExt}`); + + if (variant === "esm") { + return typesModule; + } else { + return typesModule.default; + } +}; diff --git a/lib/nodejs/test/include.test.mjs b/lib/nodejs/test/include.test.mjs new file mode 100644 index 00000000000..70c7b242f6f --- /dev/null +++ b/lib/nodejs/test/include.test.mjs @@ -0,0 +1,18 @@ +import test from "tape"; +import { IncludeTest as IncludeTestEs5 } from "./gen-nodejs/Include_types.js"; +import { IncludeTest as IncludeTestEs6 } from "./gen-nodejs-es6/Include_types.js"; +import { IncludeTest as IncludeTestEsm } from "./gen-nodejs-esm/Include_types.mjs"; + +function constructTest(classVariant) { + return function (t) { + const obj = new classVariant({ bools: { im_true: true, im_false: false } }); + + t.assert(obj.bools.im_true === true); + t.assert(obj.bools.im_false === false); + t.end(); + }; +} + +test("construct es5", constructTest(IncludeTestEs5)); +test("construct es6", constructTest(IncludeTestEs6)); +test("construct esm", constructTest(IncludeTestEsm)); diff --git a/lib/nodejs/test/int64.test.js b/lib/nodejs/test/int64.test.js index 27ad28c003f..21d4d58a6a8 100644 --- a/lib/nodejs/test/int64.test.js +++ b/lib/nodejs/test/int64.test.js @@ -23,7 +23,7 @@ const i64types = require("./gen-nodejs-es6/Int64Test_types.js"); const test = require("tape"); const cases = { - "should correctly generate Int64 constants": function(assert) { + "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); @@ -39,7 +39,7 @@ const cases = { EXPECTED_MAX_JS_SAFE_PLUS_ONE_INT64, EXPECTED_MIN_JS_SAFE_MINUS_ONE_INT64, EXPECTED_MAX_SIGNED_INT64, - EXPECTED_MIN_SIGNED_INT64 + EXPECTED_MIN_SIGNED_INT64, ]; assert.ok(EXPECTED_SMALL_INT64.equals(i64types.SMALL_INT64)); @@ -47,27 +47,27 @@ const cases = { 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 - ) + i64types.MAX_JS_SAFE_PLUS_ONE_INT64, + ), ); assert.ok( EXPECTED_MIN_JS_SAFE_MINUS_ONE_INT64.equals( - i64types.MIN_JS_SAFE_MINUS_ONE_INT64 - ) + 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() + i64types.SMALL_INT64.toNumber(), ); assert.equal( Number.MAX_SAFE_INTEGER, - i64types.MAX_JS_SAFE_INT64.toNumber() + i64types.MAX_JS_SAFE_INT64.toNumber(), ); assert.equal( Number.MIN_SAFE_INTEGER, - i64types.MIN_JS_SAFE_INT64.toNumber() + i64types.MIN_JS_SAFE_INT64.toNumber(), ); for (let i = 0; i < EXPECTED_INT64_LIST.length; ++i) { @@ -79,14 +79,14 @@ const cases = { assert.ok( i64types.INT64_2_INT64_MAP[ JSONInt64.toDecimalString(int64Object) - ].equals(int64Object) + ].equals(int64Object), ); } assert.end(); - } + }, }; -Object.keys(cases).forEach(function(caseName) { +Object.keys(cases).forEach(function (caseName) { test(caseName, cases[caseName]); }); diff --git a/lib/nodejs/test/package-lock.json b/lib/nodejs/test/package-lock.json new file mode 100644 index 00000000000..e7f9543794f --- /dev/null +++ b/lib/nodejs/test/package-lock.json @@ -0,0 +1,52 @@ +{ + "name": "test", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "devDependencies": { + "thrift": "file:../../.." + } + }, + "../../..": { + "version": "0.22.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "browser-or-node": "^1.2.1", + "isomorphic-ws": "^4.0.1", + "node-int64": "^0.4.0", + "q": "^1.5.0", + "ws": "^5.2.3" + }, + "devDependencies": { + "@eslint/js": "^9.18.0", + "@types/node": "^22.10.5", + "@types/node-int64": "^0.4.29", + "@types/q": "^1.5.1", + "buffer-equals": "^1.0.4", + "commander": "^13.0.0", + "connect": "^3.6.6", + "eslint": "^9.18.0", + "eslint-config-prettier": "^10.0.1", + "eslint-plugin-prettier": "^5.2.1", + "globals": "^15.14.0", + "html-validator-cli": "^2.0.0", + "jsdoc": "^4.0.2", + "json-int64": "^1.0.2", + "nyc": "^15.0.0", + "prettier": "^3.4.2", + "tape": "^4.9.0", + "typescript": "^5.7.2", + "utf-8-validate": "^5.0.0" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/thrift": { + "resolved": "../../..", + "link": true + } + } +} diff --git a/lib/nodejs/test/package.json b/lib/nodejs/test/package.json new file mode 100644 index 00000000000..22220ec724a --- /dev/null +++ b/lib/nodejs/test/package.json @@ -0,0 +1,5 @@ +{ + "devDependencies": { + "thrift": "file:../../.." + } +} diff --git a/lib/nodejs/test/server.js b/lib/nodejs/test/server.mjs similarity index 68% rename from lib/nodejs/test/server.js rename to lib/nodejs/test/server.mjs index 677839aea2b..7a3c593c07f 100644 --- a/lib/nodejs/test/server.js +++ b/lib/nodejs/test/server.mjs @@ -19,56 +19,62 @@ * under the License. */ -const fs = require("fs"); -const path = require("path"); -const thrift = require("../lib/thrift"); -const program = require("commander"); -const helpers = require("./helpers"); +import fs from "fs"; +import path from "path"; +import thrift from "thrift"; +import { program } from "commander"; +import helpers from "./helpers.js"; program .option( "-p, --protocol ", "Set thrift protocol (binary|compact|json)", - "binary" + "binary", ) .option( "-t, --transport ", "Set thrift transport (buffered|framed|http)", - "buffered" + "buffered", ) .option("--ssl", "use ssl transport") .option("--port ", "Set thrift server port", 9090) .option("--domain-socket ", "Set thift server unix domain socket") .option( - "-t, --type ", + "--type ", "Select server type (http|multiplex|tcp|websocket)", - "tcp" + "tcp", ) .option("--callback", "test with callback style functions") .option("--es6", "Use es6 code") .option("--es5", "Use es5 code") + .option("--esm", "Use es modules") .parse(process.argv); -const ThriftTest = require(`./${helpers.genPath}/ThriftTest`); -const SecondService = require(`./${helpers.genPath}/SecondService`); -const { ThriftTestHandler } = require("./test_handler"); - -const port = program.port; -const domainSocket = program.domainSocket; -const ssl = program.ssl; - -let type = program.type; -if (program.transport === "http") { - program.transport = "buffered"; +const ThriftTest = await import( + `./${helpers.genPath}/ThriftTest.${helpers.moduleExt}` +); +const SecondService = await import( + `./${helpers.genPath}/SecondService.${helpers.moduleExt}` +); +import { ThriftTestHandler } from "./test_handler.mjs"; + +const opts = program.opts(); +const port = opts.port; +const domainSocket = opts.domainSocket; +const ssl = opts.ssl; + +let type = opts.type; +if (opts.transport === "http") { + opts.transport = "buffered"; type = "http"; -} else if (program.transport === "websocket") { - program.transport = "buffered"; +} else if (opts.transport === "websocket") { + opts.transport = "buffered"; type = "websocket"; } let options = { - transport: helpers.transports[program.transport], - protocol: helpers.protocols[program.protocol] + transport: helpers.transports[opts.transport], + protocol: helpers.protocols[opts.protocol], }; if (type === "http" || type === "websocket") { @@ -78,30 +84,30 @@ if (type === "http" || type === "websocket") { options = { services: { "/test": options }, cors: { - "*": true - } + "*": true, + }, }; } let processor; if (type === "multiplex") { const SecondServiceHandler = { - secondtestString: function(thing, result) { + secondtestString: function (thing, result) { console.log('testString("' + thing + '")'); result(null, 'testString("' + thing + '")'); - } + }, }; processor = new thrift.MultiplexedProcessor(); processor.registerProcessor( "ThriftTest", - new ThriftTest.Processor(ThriftTestHandler) + new ThriftTest.Processor(ThriftTestHandler), ); processor.registerProcessor( "SecondService", - new SecondService.Processor(SecondServiceHandler) + new SecondService.Processor(SecondServiceHandler), ); } @@ -113,8 +119,8 @@ if (ssl) { type === "websocket" ) { options.tls = { - key: fs.readFileSync(path.resolve(__dirname, "server.key")), - cert: fs.readFileSync(path.resolve(__dirname, "server.crt")) + key: fs.readFileSync(path.resolve(import.meta.dirname, "server.key")), + cert: fs.readFileSync(path.resolve(import.meta.dirname, "server.crt")), }; } } diff --git a/lib/nodejs/test/test-cases.js b/lib/nodejs/test/test-cases.mjs similarity index 79% rename from lib/nodejs/test/test-cases.js rename to lib/nodejs/test/test-cases.mjs index 02c566fbf53..543e3539ce1 100644 --- a/lib/nodejs/test/test-cases.js +++ b/lib/nodejs/test/test-cases.mjs @@ -19,13 +19,14 @@ "use strict"; -const helpers = require("./helpers"); -const ttypes = require(`./${helpers.genPath}/ThriftTest_types`); -const Int64 = require("node-int64"); +import helpers from "./helpers.js"; +import Int64 from "node-int64"; + +const ttypes = await helpers.importTypes(`ThriftTest_types`); //all Languages in UTF-8 /*jshint -W100 */ -const stringTest = (module.exports.stringTest = +export const stringTest = "Afrikaans, Alemannisch, Aragonés, العربية, مصرى, " + "Asturianu, Aymar aru, Azərbaycan, Башҡорт, Boarisch, Žemaitėška, " + "Беларуская, Беларуская (тарашкевіца), Български, Bamanankan, " + @@ -50,27 +51,27 @@ const stringTest = (module.exports.stringTest = "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ú, 粵語"); + "Bân-lâm-gú, 粵語"; /*jshint +W100 */ -const specialCharacters = (module.exports.specialCharacters = +export const 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: !@#$%&()(&%$#{}{}<><><" + - ' char-to-test-json-parsing: ]] "]] \\" }}}{ [[[ '); + ' char-to-test-json-parsing: ]] "]] \\" }}}{ [[[ '; -const mapTestInput = (module.exports.mapTestInput = { +export const mapTestInput = { a: "123", "a b": "with spaces ", same: "same", - "0": "numeric key", + 0: "numeric key", longValue: stringTest, - stringTest: "long key" -}); + stringTest: "long key", +}; -const simple = [ +export const simple = [ ["testVoid", undefined], ["testString", "Test"], ["testString", ""], @@ -93,9 +94,9 @@ const simple = [ ["testI64", new Int64(new Buffer([0, 0x20, 0, 0, 0, 0, 0, 1]))], // 2^53+1 [ "testI64", - new Int64(new Buffer([0xff, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff])) + new Int64(new Buffer([0xff, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff])), ], // -2^53-1 - ["testTypedef", 69] + ["testTypedef", 69], ]; const mapout = {}; @@ -103,78 +104,68 @@ for (let i = 0; i < 5; ++i) { mapout[i] = i - 10; } -const deep = [ +export const deep = [ [ "testList", - [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20] - ] + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], + ], ]; -const deepUnordered = [ +export const deepUnordered = [ ["testMap", mapout], ["testSet", [1, 2, 3]], - ["testStringMap", mapTestInput] + ["testStringMap", mapTestInput], ]; -const out = new ttypes.Xtruct({ +export const out = new ttypes.Xtruct({ string_thing: "Zero", byte_thing: 1, i32_thing: -3, - i64_thing: 1000000 + i64_thing: 1000000, }); -const out2 = new ttypes.Xtruct2(); +export const out2 = new ttypes.Xtruct2(); out2.byte_thing = 1; out2.struct_thing = out; out2.i32_thing = 5; -const crazy = new ttypes.Insanity({ - userMap: { "5": 5, "8": 8 }, +export const crazy = new ttypes.Insanity({ + userMap: { 5: 5, 8: 8 }, xtructs: [ new ttypes.Xtruct({ string_thing: "Goodbye4", byte_thing: 4, i32_thing: 4, - i64_thing: 4 + i64_thing: 4, }), new ttypes.Xtruct({ string_thing: "Hello2", byte_thing: 2, i32_thing: 2, - i64_thing: 2 - }) - ] + i64_thing: 2, + }), + ], }); -const crazy2 = new ttypes.Insanity({ - userMap: { "5": 5, "8": 8 }, +export const crazy2 = new ttypes.Insanity({ + userMap: { 5: 5, 8: 8 }, xtructs: [ { string_thing: "Goodbye4", byte_thing: 4, i32_thing: 4, - i64_thing: 4 + i64_thing: 4, }, { string_thing: "Hello2", byte_thing: 2, i32_thing: 2, - i64_thing: 2 - } - ] + i64_thing: 2, + }, + ], }); -const insanity = { - "1": { "2": crazy, "3": crazy }, - "2": { "6": { userMap: {}, xtructs: [] } } +export const insanity = { + 1: { 2: crazy, 3: crazy }, + 2: { 6: { userMap: {}, xtructs: [] } }, }; - -module.exports.simple = simple; -module.exports.deep = deep; -module.exports.deepUnordered = deepUnordered; - -module.exports.out = out; -module.exports.out2 = out2; -module.exports.crazy = crazy; -module.exports.crazy2 = crazy2; -module.exports.insanity = insanity; diff --git a/lib/nodejs/test/testAll.sh b/lib/nodejs/test/testAll.sh index 37b6b438d42..a3baa6e438b 100755 --- a/lib/nodejs/test/testAll.sh +++ b/lib/nodejs/test/testAll.sh @@ -35,25 +35,23 @@ REPORT_PREFIX="${DIR}/../coverage/report" COUNT=0 -export NODE_PATH="${DIR}:${DIR}/../lib:${NODE_PATH}" - testServer() { - echo " [ECMA $1] Testing $2 Client/Server with protocol $3 and transport $4 $5"; + echo " [Variant: $1] Testing $2 Client/Server with protocol $3 and transport $4 $5"; RET=0 if [ -n "${COVER}" ]; then - ${ISTANBUL} cover ${DIR}/server.js --dir ${REPORT_PREFIX}${COUNT} --handle-sigint -- --type $2 -p $3 -t $4 $5 & + ${ISTANBUL} cover ${DIR}/server.mjs --dir ${REPORT_PREFIX}${COUNT} --handle-sigint -- --type $2 -p $3 -t $4 $5 & COUNT=$((COUNT+1)) else - node ${DIR}/server.js --${1} --type $2 -p $3 -t $4 $5 & + node ${DIR}/server.mjs --${1} --type $2 -p $3 -t $4 $5 & fi SERVERPID=$! sleep 0.1 if [ -n "${COVER}" ]; then - ${ISTANBUL} cover ${DIR}/client.js --dir ${REPORT_PREFIX}${COUNT} -- --${1} --type $2 -p $3 -t $4 $5 || RET=1 + ${ISTANBUL} cover ${DIR}/client.mjs --dir ${REPORT_PREFIX}${COUNT} -- --${1} --type $2 -p $3 -t $4 $5 || RET=1 COUNT=$((COUNT+1)) else - node ${DIR}/client.js --${1} --type $2 -p $3 -t $4 $5 || RET=1 + node ${DIR}/client.mjs --${1} --type $2 -p $3 -t $4 $5 || RET=1 fi kill -2 $SERVERPID || RET=1 wait $SERVERPID @@ -90,10 +88,17 @@ TESTOK=0 ${THRIFT_COMPILER} -o ${DIR} --gen js:node ${THRIFT_FILES_DIR}/v0.16/ThriftTest.thrift ${THRIFT_COMPILER} -o ${DIR} --gen js:node ${THRIFT_FILES_DIR}/JsDeepConstructorTest.thrift ${THRIFT_COMPILER} -o ${DIR} --gen js:node ${THRIFT_FILES_DIR}/Int64Test.thrift +${THRIFT_COMPILER} -o ${DIR} --gen js:node ${THRIFT_FILES_DIR}/Include.thrift mkdir ${DIR}/gen-nodejs-es6 ${THRIFT_COMPILER} -out ${DIR}/gen-nodejs-es6 --gen js:node,es6 ${THRIFT_FILES_DIR}/v0.16/ThriftTest.thrift ${THRIFT_COMPILER} -out ${DIR}/gen-nodejs-es6 --gen js:node,es6 ${THRIFT_FILES_DIR}/JsDeepConstructorTest.thrift ${THRIFT_COMPILER} -out ${DIR}/gen-nodejs-es6 --gen js:node,es6 ${THRIFT_FILES_DIR}/Int64Test.thrift +${THRIFT_COMPILER} -out ${DIR}/gen-nodejs-es6 --gen js:node,es6 ${THRIFT_FILES_DIR}/Include.thrift +mkdir ${DIR}/gen-nodejs-esm +${THRIFT_COMPILER} -out ${DIR}/gen-nodejs-esm --gen js:node,es6,esm ${THRIFT_FILES_DIR}/v0.16/ThriftTest.thrift +${THRIFT_COMPILER} -out ${DIR}/gen-nodejs-esm --gen js:node,es6,esm ${THRIFT_FILES_DIR}/JsDeepConstructorTest.thrift +${THRIFT_COMPILER} -out ${DIR}/gen-nodejs-esm --gen js:node,es6,esm ${THRIFT_FILES_DIR}/Int64Test.thrift +${THRIFT_COMPILER} -out ${DIR}/gen-nodejs-esm --gen js:node,es6,esm ${THRIFT_FILES_DIR}/Include.thrift # generate episodic compilation test code TYPES_PACKAGE=${EPISODIC_DIR}/node_modules/types-package @@ -118,8 +123,10 @@ fi # unit tests node ${DIR}/binary.test.js || TESTOK=1 +node ${DIR}/header.test.js || TESTOK=1 node ${DIR}/int64.test.js || TESTOK=1 node ${DIR}/deep-constructor.test.js || TESTOK=1 +node ${DIR}/include.test.mjs || TESTOK=1 # integration tests @@ -129,11 +136,11 @@ do do for transport in buffered framed do - for ecma_version in es5 es6 + for gen_variant in es5 es6 esm do - testServer $ecma_version $type $protocol $transport || TESTOK=1 - testServer $ecma_version $type $protocol $transport --ssl || TESTOK=1 - testServer $ecma_version $type $protocol $transport --callback || TESTOK=1 + testServer $gen_variant $type $protocol $transport || TESTOK=1 + testServer $gen_variant $type $protocol $transport --ssl || TESTOK=1 + testServer $gen_variant $type $protocol $transport --callback || TESTOK=1 done done done diff --git a/lib/nodejs/test/test_driver.js b/lib/nodejs/test/test_driver.mjs similarity index 78% rename from lib/nodejs/test/test_driver.js rename to lib/nodejs/test/test_driver.mjs index 7c9a91914bf..eca56ba773c 100644 --- a/lib/nodejs/test/test_driver.js +++ b/lib/nodejs/test/test_driver.mjs @@ -26,26 +26,31 @@ // supports an optional callback function which is called with // a status message when the test is complete. -const test = require("tape"); +import test from "tape"; -const helpers = require("./helpers"); -const ttypes = require(`./${helpers.genPath}/ThriftTest_types`); -const TException = require("thrift").Thrift.TException; -const Int64 = require("node-int64"); -const testCases = require("./test-cases"); +import helpers from "./helpers.js"; +import thrift from "thrift"; +import Int64 from "node-int64"; +import * as testCases from "./test-cases.mjs"; -exports.ThriftTestDriver = function(client, callback) { +const ttypes = await import( + `./${helpers.genPath}/ThriftTest_types.${helpers.moduleExt}` +); + +const TException = thrift.Thrift.TException; + +export const ThriftTestDriver = function (client, callback) { test( "NodeJS Style Callback Client Tests", { skip: helpers.ecmaMode === "es6" }, - function(assert) { + function (assert) { const checkRecursively = makeRecursiveCheck(assert); function makeAsserter(assertionFn) { - return function(c) { + return function (c) { const fnName = c[0]; const expected = c[1]; - client[fnName](expected, function(err, actual) { + client[fnName](expected, function (err, actual) { assert.error(err, fnName + ": no callback error"); assertionFn(actual, expected, fnName); }); @@ -53,18 +58,18 @@ exports.ThriftTestDriver = function(client, callback) { } testCases.simple.forEach( - makeAsserter(function(a, e, m) { + makeAsserter(function (a, e, m) { if (a instanceof Int64) { const e64 = e instanceof Int64 ? e : new Int64(e); assert.deepEqual(a.buffer, e64.buffer, m); } else { assert.equal(a, e, m); } - }) + }), ); testCases.deep.forEach(makeAsserter(assert.deepEqual)); testCases.deepUnordered.forEach( - makeAsserter(makeUnorderedDeepEqual(assert)) + makeAsserter(makeUnorderedDeepEqual(assert)), ); const arr = []; @@ -72,106 +77,106 @@ exports.ThriftTestDriver = function(client, callback) { arr[i] = 255 - i; } let buf = new Buffer(arr); - client.testBinary(buf, function(err, response) { + client.testBinary(buf, function (err, response) { assert.error(err, "testBinary: no callback error"); assert.equal(response.length, 256, "testBinary"); assert.deepEqual(response, buf, "testBinary(Buffer)"); }); buf = new Buffer(arr); - client.testBinary(buf.toString("binary"), function(err, response) { + client.testBinary(buf.toString("binary"), function (err, response) { assert.error(err, "testBinary: no callback error"); assert.equal(response.length, 256, "testBinary"); assert.deepEqual(response, buf, "testBinary(string)"); }); - client.testMapMap(42, function(err, response) { + client.testMapMap(42, function (err, response) { const expected = { - "4": { "1": 1, "2": 2, "3": 3, "4": 4 }, - "-4": { "-4": -4, "-3": -3, "-2": -2, "-1": -1 } + 4: { 1: 1, 2: 2, 3: 3, 4: 4 }, + "-4": { "-4": -4, "-3": -3, "-2": -2, "-1": -1 }, }; assert.error(err, "testMapMap: no callback error"); assert.deepEqual(expected, response, "testMapMap"); }); - client.testStruct(testCases.out, function(err, response) { + client.testStruct(testCases.out, function (err, response) { assert.error(err, "testStruct: no callback error"); checkRecursively(testCases.out, response, "testStruct"); }); - client.testNest(testCases.out2, function(err, response) { + client.testNest(testCases.out2, function (err, response) { assert.error(err, "testNest: no callback error"); checkRecursively(testCases.out2, response, "testNest"); }); - client.testInsanity(testCases.crazy, function(err, response) { + client.testInsanity(testCases.crazy, function (err, response) { assert.error(err, "testInsanity: no callback error"); checkRecursively(testCases.insanity, response, "testInsanity"); }); - client.testInsanity(testCases.crazy2, function(err, response) { + client.testInsanity(testCases.crazy2, function (err, response) { assert.error(err, "testInsanity2: no callback error"); checkRecursively(testCases.insanity, response, "testInsanity2"); }); - client.testException("TException", function(err, response) { + client.testException("TException", function (err, response) { assert.ok( err instanceof TException, - "testException: correct error type" + "testException: correct error type", ); assert.ok(!response, "testException: no response"); }); - client.testException("Xception", function(err, response) { + client.testException("Xception", function (err, response) { assert.ok( err instanceof ttypes.Xception, - "testException: correct error type" + "testException: correct error type", ); assert.ok(!response, "testException: no response"); assert.equal(err.errorCode, 1001, "testException: correct error code"); assert.equal( "Xception", err.message, - "testException: correct error message" + "testException: correct error message", ); }); - client.testException("no Exception", function(err, response) { + client.testException("no Exception", function (err, response) { assert.error(err, "testException: no callback error"); assert.ok(!response, "testException: no response"); }); - client.testOneway(0, function(err, response) { + client.testOneway(0, function (err, response) { assert.error(err, "testOneway: no callback error"); assert.strictEqual(response, undefined, "testOneway: void response"); }); - checkOffByOne(function(done) { - client.testI32(-1, function(err, response) { + checkOffByOne(function (done) { + client.testI32(-1, function (err, response) { assert.error(err, "checkOffByOne: no callback error"); assert.equal(-1, response); assert.end(); done(); }); }, callback); - } + }, ); // ES6 does not support callback style if (helpers.ecmaMode === "es6") { - checkOffByOne(done => done(), callback); + checkOffByOne((done) => done(), callback); } }; -exports.ThriftTestDriverPromise = function(client, callback) { - test("Promise Client Tests", function(assert) { +export const ThriftTestDriverPromise = function (client, callback) { + test("Promise Client Tests", function (assert) { const checkRecursively = makeRecursiveCheck(assert); function makeAsserter(assertionFn) { - return function(c) { + return function (c) { const fnName = c[0]; const expected = c[1]; client[fnName](expected) - .then(function(actual) { + .then(function (actual) { assertionFn(actual, expected, fnName); }) .catch(() => assert.fail("fnName")); @@ -179,63 +184,63 @@ exports.ThriftTestDriverPromise = function(client, callback) { } testCases.simple.forEach( - makeAsserter(function(a, e, m) { + makeAsserter(function (a, e, m) { if (a instanceof Int64) { const e64 = e instanceof Int64 ? e : new Int64(e); assert.deepEqual(a.buffer, e64.buffer, m); } else { assert.equal(a, e, m); } - }) + }), ); testCases.deep.forEach(makeAsserter(assert.deepEqual)); testCases.deepUnordered.forEach( - makeAsserter(makeUnorderedDeepEqual(assert)) + makeAsserter(makeUnorderedDeepEqual(assert)), ); client .testStruct(testCases.out) - .then(function(response) { + .then(function (response) { checkRecursively(testCases.out, response, "testStruct"); }) .catch(() => assert.fail("testStruct")); client .testNest(testCases.out2) - .then(function(response) { + .then(function (response) { checkRecursively(testCases.out2, response, "testNest"); }) .catch(() => assert.fail("testNest")); client .testInsanity(testCases.crazy) - .then(function(response) { + .then(function (response) { checkRecursively(testCases.insanity, response, "testInsanity"); }) .catch(() => assert.fail("testInsanity")); client .testInsanity(testCases.crazy2) - .then(function(response) { + .then(function (response) { checkRecursively(testCases.insanity, response, "testInsanity2"); }) .catch(() => assert.fail("testInsanity2")); client .testException("TException") - .then(function() { + .then(function () { assert.fail("testException: TException"); }) - .catch(function(err) { + .catch(function (err) { assert.ok(err instanceof TException); }); client .testException("Xception") - .then(function() { + .then(function () { assert.fail("testException: Xception"); }) - .catch(function(err) { + .catch(function (err) { assert.ok(err instanceof ttypes.Xception); assert.equal(err.errorCode, 1001); assert.equal("Xception", err.message); @@ -243,22 +248,22 @@ exports.ThriftTestDriverPromise = function(client, callback) { client .testException("no Exception") - .then(function(response) { + .then(function (response) { assert.equal(undefined, response); //void }) .catch(() => assert.fail("testException")); client .testOneway(0) - .then(function(response) { + .then(function (response) { assert.strictEqual(response, undefined, "testOneway: void response"); }) .catch(() => assert.fail("testOneway: should not reject")); - checkOffByOne(function(done) { + checkOffByOne(function (done) { client .testI32(-1) - .then(function(response) { + .then(function (response) { assert.equal(-1, response); assert.end(); done(); @@ -272,7 +277,7 @@ exports.ThriftTestDriverPromise = function(client, callback) { // ========================================================= function makeRecursiveCheck(assert) { - return function(map1, map2, msg) { + return function (map1, map2, msg) { const equal = checkRecursively(map1, map2); assert.ok(equal, msg); @@ -295,7 +300,7 @@ function makeRecursiveCheck(assert) { return map1 == map2; } } else { - return Object.keys(map1).every(function(key) { + return Object.keys(map1).every(function (key) { return checkRecursively(map1[key], map2[key]); }); } @@ -319,7 +324,7 @@ function checkOffByOne(done, callback) { * Because this is the last test against the server, when it completes * the entire suite is complete by definition (the tests run serially). */ - done(function() { + done(function () { test_complete = true; }); @@ -334,7 +339,7 @@ function checkOffByOne(done, callback) { callback( "Server test failed to complete after " + (retry_limit * retry_interval) / 1000 + - " seconds" + " seconds", ); } } @@ -344,7 +349,7 @@ function checkOffByOne(done, callback) { } function makeUnorderedDeepEqual(assert) { - return function(actual, expected, name) { + return function (actual, expected, name) { assert.equal(actual.length, expected.length, name); for (const k in actual) { let found = false; diff --git a/lib/nodejs/test/test_handler.js b/lib/nodejs/test/test_handler.mjs similarity index 91% rename from lib/nodejs/test/test_handler.js rename to lib/nodejs/test/test_handler.mjs index 317a7c81016..a378fe16e72 100644 --- a/lib/nodejs/test/test_handler.js +++ b/lib/nodejs/test/test_handler.mjs @@ -19,12 +19,14 @@ //This is the server side Node test handler for the standard // Apache Thrift test service. -const helpers = require("./helpers"); -const ttypes = require(`./${helpers.genPath}/ThriftTest_types`); -const TException = require("thrift").Thrift.TException; +import helpers from "./helpers.js"; +import thrift from "thrift"; + +const ttypes = await helpers.importTypes(`ThriftTest_types`); +const TException = thrift.Thrift.TException; function makeSyncHandler() { - return function(thing) { + return function (thing) { return thing; }; } @@ -36,11 +38,11 @@ const syncHandlers = { testMulti: testMulti, testException: testException, testMultiException: testMultiException, - testOneway: testOneway + testOneway: testOneway, }; function makeAsyncHandler(label) { - return function(thing, result) { + return function (thing, result) { thing = syncHandlers[label](thing); result(null, thing); }; @@ -51,7 +53,7 @@ const asyncHandlers = { testMulti: testMultiAsync, testException: testExceptionAsync, testMultiException: testMultiExceptionAsync, - testOneway: testOnewayAsync + testOneway: testOnewayAsync, }; const identityHandlers = [ @@ -69,7 +71,7 @@ const identityHandlers = [ "testSet", "testList", "testEnum", - "testTypedef" + "testTypedef", ]; function testVoid() { @@ -208,13 +210,13 @@ function testOnewayAsync(sleepFor) { testOneway(sleepFor); } -identityHandlers.forEach(function(label) { +identityHandlers.forEach(function (label) { syncHandlers[label] = makeSyncHandler(label); asyncHandlers[label] = makeAsyncHandler(label); }); -["testMapMap", "testInsanity"].forEach(function(label) { +["testMapMap", "testInsanity"].forEach(function (label) { asyncHandlers[label] = makeAsyncHandler(label); }); -exports.ThriftTestHandler = asyncHandlers; +export { asyncHandlers as ThriftTestHandler }; diff --git a/lib/nodets/Makefile.am b/lib/nodets/Makefile.am index 02d0c11fee7..ac2aa6e1b17 100644 --- a/lib/nodets/Makefile.am +++ b/lib/nodets/Makefile.am @@ -41,6 +41,9 @@ clean-local: $(RM) -r $(top_srcdir)/node_modules $(RM) -r test-compiled +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ test \ coding_standards.md diff --git a/lib/nodets/test/client.ts b/lib/nodets/test/client.ts index 4fa3c2868dd..c2666bc0d86 100644 --- a/lib/nodets/test/client.ts +++ b/lib/nodets/test/client.ts @@ -25,29 +25,30 @@ import test_driver = require("./test_driver"); import ThriftTestDriver = test_driver.ThriftTestDriver; import ThriftTestDriverPromise = test_driver.ThriftTestDriverPromise; -// var program = require("commander"); -import * as program from "commander"; +import { program } from "commander"; program - .option("--port ", "Set thrift server port number to connect", 9090) + .option("--port ", "Set thrift server port number to connect", Number.parseInt, 9090) .option("--promise", "test with promise style functions") .option("--protocol", "Set thrift protocol (binary) [protocol]") .parse(process.argv); -var port: number = program.port; -var promise = program.promise; + +var opts = program.opts(); +var port: number = opts.port; +var promise = opts.promise; var options = { transport: Thrift.TBufferedTransport, - protocol: Thrift.TBinaryProtocol + protocol: Thrift.TBinaryProtocol, }; var testDriver = promise ? ThriftTestDriverPromise : ThriftTestDriver; var connection = thrift.createConnection("localhost", port, options); -connection.on("error", function(err: string) { - assert(false, err); +connection.on("error", function (err: string) { + assert(false, err); }); var client = thrift.createClient(ThriftTest.Client, connection); @@ -60,4 +61,4 @@ function runTests() { }); } -exports.expressoTest = function() {}; +exports.expressoTest = function () {}; diff --git a/lib/nodets/test/int64.test.ts b/lib/nodets/test/int64.test.ts index d209234b50c..bb0345851e1 100644 --- a/lib/nodets/test/int64.test.ts +++ b/lib/nodets/test/int64.test.ts @@ -18,18 +18,26 @@ */ import Int64 = require("node-int64"); -import JSONInt64 = require('json-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) { + "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_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[] = [ @@ -39,7 +47,7 @@ const cases = { EXPECTED_MAX_JS_SAFE_PLUS_ONE_INT64, EXPECTED_MIN_JS_SAFE_MINUS_ONE_INT64, EXPECTED_MAX_SIGNED_INT64, - EXPECTED_MIN_SIGNED_INT64 + EXPECTED_MIN_SIGNED_INT64, ]; assert.ok(EXPECTED_SMALL_INT64.equals(i64types.SMALL_INT64)); @@ -47,42 +55,46 @@ const cases = { 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 - ) + i64types.MAX_JS_SAFE_PLUS_ONE_INT64, + ), ); assert.ok( EXPECTED_MIN_JS_SAFE_MINUS_ONE_INT64.equals( - i64types.MIN_JS_SAFE_MINUS_ONE_INT64 - ) + 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() + i64types.SMALL_INT64.toNumber(), ); assert.equal( Number.MAX_SAFE_INTEGER, - i64types.MAX_JS_SAFE_INT64.toNumber() + i64types.MAX_JS_SAFE_INT64.toNumber(), ); assert.equal( Number.MIN_SAFE_INTEGER, - i64types.MIN_JS_SAFE_INT64.toNumber() + 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){ + 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.ok( + i64types.INT64_2_INT64_MAP[ + JSONInt64.toDecimalString(int64Object) + ].equals(int64Object), + ); } assert.end(); - } + }, }; -Object.keys(cases).forEach(function(caseName) { +Object.keys(cases).forEach(function (caseName) { test(caseName, cases[caseName]); }); diff --git a/lib/nodets/test/server.ts b/lib/nodets/test/server.ts index 2da53aee29b..59113840a41 100644 --- a/lib/nodets/test/server.ts +++ b/lib/nodets/test/server.ts @@ -1,26 +1,31 @@ import thrift = require("thrift"); -var program = require('commander'); +import { program } from 'commander'; import ThriftTest = require('./gen-nodejs/ThriftTest'); import test_handler = require('./test_handler'); program - .option('--port ', 'Set thrift server port', 9090) + .option('--port ', 'Set thrift server port', Number.parseInt, 9090) .option('--promise', 'test with promise style functions') .option('--protocol', '"Set thrift protocol (binary) [protocol]"') .parse(process.argv); -var port: number = program.port; +var opts = program.opts(); +var port: number = opts.port; var options: thrift.ServerOptions = { transport: thrift.TBufferedTransport, - protocol: thrift.TBinaryProtocol + protocol: thrift.TBinaryProtocol, }; var server: thrift.Server; -if (program.promise) { +if (opts.promise) { server = thrift.createServer(ThriftTest.Processor, new test_handler.AsyncThriftTestHandler(), options); } else { - server = thrift.createServer(ThriftTest.Processor, new test_handler.SyncThriftTestHandler(), options); + server = thrift.createServer( + ThriftTest.Processor, + new test_handler.SyncThriftTestHandler(), + options, + ); } server.listen(port); diff --git a/lib/nodets/test/test-cases.ts b/lib/nodets/test/test-cases.ts index 44f254e9200..98f54af5ca5 100644 --- a/lib/nodets/test/test-cases.ts +++ b/lib/nodets/test/test-cases.ts @@ -1,91 +1,100 @@ -'use strict'; +"use strict"; -import ttypes = require('./gen-nodejs/ThriftTest_types'); -import Int64 = require('node-int64'); +import ttypes = require("./gen-nodejs/ThriftTest_types"); +import Int64 = require("node-int64"); //all Languages in UTF-8 /*jshint -W100 */ -export 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, Polski, پنجابی, پښتو, " + - "Norfuk / Pitkern, 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ú, 粵語"; +export 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, Polski, پنجابی, پښتو, " + + "Norfuk / Pitkern, 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ú, 粵語"; /*jshint +W100 */ -export 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: !@#$%&()(&%$#{}{}<><><' + - ' char-to-test-json-parsing: ]] \"]] \\" }}}{ [[[ '; +export 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: !@#$%&()(&%$#{}{}<><><" + + ' char-to-test-json-parsing: ]] \"]] \\" }}}{ [[[ '; export var mapTestInput = { - "a":"123", "a b":"with spaces ", "same":"same", "0":"numeric key", - "longValue":stringTest, stringTest:"long key" + a: "123", + "a b": "with spaces ", + same: "same", + "0": "numeric key", + longValue: stringTest, + stringTest: "long key", }; export var simple = [ - ['testVoid', undefined], - ['testString', 'Test'], - ['testString', ''], - ['testString', stringTest], - ['testString', specialCharacters], - ['testByte', 1], - ['testByte', 0], - ['testByte', -1], - ['testByte', -127], - ['testI32', -1], - ['testDouble', -5.2098523], - ['testDouble', 7.012052175215044], - ['testEnum', ttypes.Numberz.ONE] + ["testVoid", undefined], + ["testString", "Test"], + ["testString", ""], + ["testString", stringTest], + ["testString", specialCharacters], + ["testByte", 1], + ["testByte", 0], + ["testByte", -1], + ["testByte", -127], + ["testI32", -1], + ["testDouble", -5.2098523], + ["testDouble", 7.012052175215044], + ["testEnum", ttypes.Numberz.ONE], ]; export var simpleLoose = [ - ['testI64', 5], - ['testI64', -5], - ['testI64', 734359738368], - ['testI64', -34359738368], - ['testI64', -734359738368], - ['testTypedef', 69] -] + ["testI64", 5], + ["testI64", -5], + ["testI64", 734359738368], + ["testI64", -34359738368], + ["testI64", -734359738368], + ["testTypedef", 69], +]; -var mapout: {[key: number]: number; } = {}; +var mapout: { [key: number]: number } = {}; for (var i = 0; i < 5; ++i) { - mapout[i] = i-10; + mapout[i] = i - 10; } export var deep = [ - ['testMap', mapout], - ['testSet', [1,2,3]], - ['testList', [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]], - ['testStringMap', mapTestInput] + ["testMap", mapout], + ["testSet", [1, 2, 3]], + [ + "testList", + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], + ], + ["testStringMap", mapTestInput], ]; export var out = new ttypes.Xtruct({ - string_thing: 'Zero', + string_thing: "Zero", byte_thing: 1, i32_thing: -3, - i64_thing: new Int64(1000000) + i64_thing: new Int64(1000000), }); export var out2 = new ttypes.Xtruct2(); @@ -94,21 +103,24 @@ out2.struct_thing = out; out2.i32_thing = 5; export var crazy = new ttypes.Insanity({ - "userMap":{ "5":new Int64(5), "8":new Int64(8) }, - "xtructs":[new ttypes.Xtruct({ - "string_thing":"Goodbye4", - "byte_thing":4, - "i32_thing":4, - "i64_thing":new Int64(4) - }), new ttypes.Xtruct({ - "string_thing":"Hello2", - "byte_thing":2, - "i32_thing":2, - "i64_thing":new Int64(2) - })] + userMap: { "5": new Int64(5), "8": new Int64(8) }, + xtructs: [ + new ttypes.Xtruct({ + string_thing: "Goodbye4", + byte_thing: 4, + i32_thing: 4, + i64_thing: new Int64(4), + }), + new ttypes.Xtruct({ + string_thing: "Hello2", + byte_thing: 2, + i32_thing: 2, + i64_thing: new Int64(2), + }), + ], }); export var insanity: any = { - "1":{ "2": crazy, "3": crazy }, - "2":{ "6":{ "userMap":{}, "xtructs":[] } } + "1": { "2": crazy, "3": crazy }, + "2": { "6": { userMap: {}, xtructs: [] } }, }; diff --git a/lib/nodets/test/test_driver.ts b/lib/nodets/test/test_driver.ts index 2c4152616ee..604d5e5836d 100644 --- a/lib/nodets/test/test_driver.ts +++ b/lib/nodets/test/test_driver.ts @@ -17,14 +17,14 @@ * under the License. */ - // This is the Node.js test driver for the standard Apache Thrift - // test service. The driver invokes every function defined in the - // Thrift Test service with a representative range of parameters. - // - // The ThriftTestDriver function requires a client object - // connected to a server hosting the Thrift Test service and - // supports an optional callback function which is called with - // a status message when the test is complete. +// This is the Node.js test driver for the standard Apache Thrift +// test service. The driver invokes every function defined in the +// Thrift Test service with a representative range of parameters. +// +// The ThriftTestDriver function requires a client object +// connected to a server hosting the Thrift Test service and +// supports an optional callback function which is called with +// a status message when the test is complete. import test = require("tape"); import ttypes = require("./gen-nodejs/ThriftTest_types"); @@ -35,107 +35,118 @@ import TException = thrift.Thrift.TException; var Int64 = require("node-int64"); import testCases = require("./test-cases"); -export function ThriftTestDriver(client: ThriftTest.Client, callback: (status: string) => void) { - - test("NodeJS Style Callback Client Tests", function(assert) { - +export function ThriftTestDriver( + client: ThriftTest.Client, + callback: (status: string) => void, +) { + test("NodeJS Style Callback Client Tests", function (assert) { var checkRecursively = makeRecursiveCheck(assert); function makeAsserter(assertionFn: (a: any, b: any, msg?: string) => void) { - return function(c: (string | any)[]) { + return function (c: (string | any)[]) { var fnName = c[0]; var expected = c[1]; - (client)[fnName](expected, function(err: any, actual: any) { + (client)[fnName](expected, function (err: any, actual: any) { assert.error(err, fnName + ": no callback error"); assertionFn(actual, expected, fnName); - }) + }); }; } testCases.simple.forEach(makeAsserter(assert.equal)); - testCases.simpleLoose.forEach(makeAsserter(function(a, e, m){ - assert.ok(a == e, m); - })); + testCases.simpleLoose.forEach( + makeAsserter(function (a, e, m) { + assert.ok(a == e, m); + }), + ); testCases.deep.forEach(makeAsserter(assert.deepEqual)); - client.testMapMap(42, function(err, response) { + client.testMapMap(42, function (err, response) { var expected: typeof response = { - "4": {"1":1, "2":2, "3":3, "4":4}, - "-4": {"-4":-4, "-3":-3, "-2":-2, "-1":-1} + "4": { "1": 1, "2": 2, "3": 3, "4": 4 }, + "-4": { "-4": -4, "-3": -3, "-2": -2, "-1": -1 }, }; - assert.error(err, 'testMapMap: no callback error'); + assert.error(err, "testMapMap: no callback error"); assert.deepEqual(expected, response, "testMapMap"); }); - client.testStruct(testCases.out, function(err, response) { + client.testStruct(testCases.out, function (err, response) { assert.error(err, "testStruct: no callback error"); checkRecursively(testCases.out, response, "testStruct"); }); - client.testNest(testCases.out2, function(err, response) { + client.testNest(testCases.out2, function (err, response) { assert.error(err, "testNest: no callback error"); checkRecursively(testCases.out2, response, "testNest"); }); - client.testInsanity(testCases.crazy, function(err, response) { + client.testInsanity(testCases.crazy, function (err, response) { assert.error(err, "testInsanity: no callback error"); checkRecursively(testCases.insanity, response, "testInsanity"); }); - client.testException("TException", function(err, response) { - assert.ok(err instanceof TException, 'testException: correct error type'); - assert.ok(!Boolean(response), 'testException: no response'); + client.testException("TException", function (err, response) { + assert.ok(err instanceof TException, "testException: correct error type"); + assert.ok(!Boolean(response), "testException: no response"); }); - client.testException("Xception", function(err, response) { - assert.ok(err instanceof ttypes.Xception, 'testException: correct error type'); - assert.ok(!Boolean(response), 'testException: no response'); - assert.equal(err.errorCode, 1001, 'testException: correct error code'); - assert.equal('Xception', err.message, 'testException: correct error message'); + client.testException("Xception", function (err, response) { + assert.ok( + err instanceof ttypes.Xception, + "testException: correct error type", + ); + assert.ok(!Boolean(response), "testException: no response"); + assert.equal(err.errorCode, 1001, "testException: correct error code"); + assert.equal( + "Xception", + err.message, + "testException: correct error message", + ); }); - client.testException("no Exception", function(err, response) { - assert.error(err, 'testException: no callback error'); - assert.ok(!Boolean(response), 'testException: no response'); + client.testException("no Exception", function (err, response) { + assert.error(err, "testException: no callback error"); + assert.ok(!Boolean(response), "testException: no response"); }); - client.testOneway(0, function(err, response) { - assert.error(err, 'testOneway: no callback error'); - assert.strictEqual(response, undefined, 'testOneway: void response'); + client.testOneway(0, function (err, response) { + assert.error(err, "testOneway: no callback error"); + assert.strictEqual(response, undefined, "testOneway: void response"); }); - checkOffByOne(function(done) { - client.testI32(-1, function(err, response) { + checkOffByOne(function (done) { + client.testI32(-1, function (err, response) { assert.error(err, "checkOffByOne: no callback error"); assert.equal(-1, response); assert.end(); done(); }); }, callback); - }); -}; - -export function ThriftTestDriverPromise(client: ThriftTest.Client, callback: (status: string) => void) { - - test("Q Promise Client Tests", function(assert) { +} +export function ThriftTestDriverPromise( + client: ThriftTest.Client, + callback: (status: string) => void, +) { + test("Q Promise Client Tests", function (assert) { var checkRecursively = makeRecursiveCheck(assert); function fail(msg: string) { - return function(error, response) { + return function (error, response) { if (error !== null) { assert.fail(msg); } - } + }; } function makeAsserter(assertionFn: (a: any, b: any, msg?: string) => void) { - return function(c: (string | any)[]) { + return function (c: (string | any)[]) { var fnName = c[0]; var expected = c[1]; - (client)[fnName](expected) - .then(function(actual: any) { + (client) + [fnName](expected) + .then(function (actual: any) { assertionFn(actual, expected, fnName); }) .fail(fail("fnName")); @@ -143,73 +154,73 @@ export function ThriftTestDriverPromise(client: ThriftTest.Client, callback: (st } testCases.simple.forEach(makeAsserter(assert.equal)); - testCases.simpleLoose.forEach(makeAsserter(function(a, e, m){ - assert.ok(a == e, m); - })); + testCases.simpleLoose.forEach( + makeAsserter(function (a, e, m) { + assert.ok(a == e, m); + }), + ); testCases.deep.forEach(makeAsserter(assert.deepEqual)); Q.resolve(client.testStruct(testCases.out)) - .then(function(response) { + .then(function (response) { checkRecursively(testCases.out, response, "testStruct"); }) .fail(fail("testStruct")); Q.resolve(client.testNest(testCases.out2)) - .then(function(response) { + .then(function (response) { checkRecursively(testCases.out2, response, "testNest"); }) .fail(fail("testNest")); Q.resolve(client.testInsanity(testCases.crazy)) - .then(function(response) { + .then(function (response) { checkRecursively(testCases.insanity, response, "testInsanity"); }) .fail(fail("testInsanity")); Q.resolve(client.testException("TException")) - .then(function(response) { + .then(function (response) { fail("testException: TException"); }) - .fail(function(err) { + .fail(function (err) { assert.ok(err instanceof TException); }); Q.resolve(client.testException("Xception")) - .then(function(response) { + .then(function (response) { fail("testException: Xception"); }) - .fail(function(err) { + .fail(function (err) { assert.ok(err instanceof ttypes.Xception); assert.equal(err.errorCode, 1001); assert.equal("Xception", err.message); }); Q.resolve(client.testException("no Exception")) - .then(function(response) { + .then(function (response) { assert.equal(undefined, response); //void }) .fail(fail("testException")); client.testOneway(0, fail("testOneway: should not answer")); - checkOffByOne(function(done) { + checkOffByOne(function (done) { Q.resolve(client.testI32(-1)) - .then(function(response) { - assert.equal(-1, response); - assert.end(); - done(); + .then(function (response) { + assert.equal(-1, response); + assert.end(); + done(); }) .fail(fail("checkOffByOne")); }, callback); }); -}; - +} // Helper Functions // ========================================================= function makeRecursiveCheck(assert: test.Test) { - return function (map1: any, map2: any, msg: string) { var equal = true; @@ -218,30 +229,37 @@ function makeRecursiveCheck(assert: test.Test) { assert.ok(equal, msg); // deepEqual doesn't work with fields using node-int64 - function checkRecursively(map1: any, map2: any) : boolean { + function checkRecursively(map1: any, map2: any): boolean { if (!(typeof map1 !== "function" && typeof map2 !== "function")) { return false; } if (!map1 || typeof map1 !== "object") { //Handle int64 types (which use node-int64 in Node.js JavaScript) - if ((typeof map1 === "number") && (typeof map2 === "object") && - (map2.buffer) && (map2.buffer instanceof Buffer) && (map2.buffer.length === 8)) { + if ( + typeof map1 === "number" && + typeof map2 === "object" && + map2.buffer && + map2.buffer instanceof Buffer && + map2.buffer.length === 8 + ) { var n = new Int64(map2.buffer); return map1 === n.toNumber(); } else { return map1 == map2; } } else { - return Object.keys(map1).every(function(key) { + return Object.keys(map1).every(function (key) { return checkRecursively(map1[key], map2[key]); }); } } - } + }; } -function checkOffByOne(done: (callback: () => void) => void, callback: (message: string) => void) { - +function checkOffByOne( + done: (callback: () => void) => void, + callback: (message: string) => void, +) { var retry_limit = 30; var retry_interval = 100; var test_complete = false; @@ -256,20 +274,23 @@ function checkOffByOne(done: (callback: () => void) => void, callback: (message: * Because this is the last test against the server, when it completes * the entire suite is complete by definition (the tests run serially). */ - done(function() { + done(function () { test_complete = true; }); //We wait up to retry_limit * retry_interval for the test suite to complete function TestForCompletion() { - if(test_complete && callback) { + if (test_complete && callback) { callback("Server successfully tested!"); } else { if (++retrys < retry_limit) { setTimeout(TestForCompletion, retry_interval); } else if (callback) { - callback("Server test failed to complete after " + - (retry_limit * retry_interval / 1000) + " seconds"); + callback( + "Server test failed to complete after " + + (retry_limit * retry_interval) / 1000 + + " seconds", + ); } } } diff --git a/lib/nodets/test/test_handler.ts b/lib/nodets/test/test_handler.ts index 996c32a5a32..823b4e7ee03 100644 --- a/lib/nodets/test/test_handler.ts +++ b/lib/nodets/test/test_handler.ts @@ -26,7 +26,6 @@ import Thrift = thrift.Thrift; import Q = require("q"); import Int64 = require("node-int64"); - export class SyncThriftTestHandler { testVoid(): Q.IPromise { //console.log('testVoid()'); @@ -35,9 +34,9 @@ export class SyncThriftTestHandler { testMapMap(hello: number) { //console.log('testMapMap(' + hello + ')'); - var mapmap: {[key: number]: {[key: number]: number; }} = []; - var pos: {[key: number]: number; } = []; - var neg: {[key: number]: number; } = []; + var mapmap: { [key: number]: { [key: number]: number } } = []; + var pos: { [key: number]: number } = []; + var neg: { [key: number]: number } = []; for (var i = 1; i < 5; i++) { pos[i] = i; neg[-i] = -i; @@ -47,53 +46,60 @@ export class SyncThriftTestHandler { return Q.resolve(mapmap); } - testInsanity(argument: ttypes.Insanity): Q.IPromise<{ [k: number]: any; }> { - const first_map: { [k: number]: any; } = []; - const second_map: { [k: number]: any; } = []; - + testInsanity(argument: ttypes.Insanity): Q.IPromise<{ [k: number]: any }> { + const first_map: { [k: number]: any } = []; + const second_map: { [k: number]: any } = []; + first_map[ttypes.Numberz.TWO] = argument; first_map[ttypes.Numberz.THREE] = argument; - + const looney = new ttypes.Insanity(); second_map[ttypes.Numberz.SIX] = looney; - - const insane: { [k: number]: any; } = []; + + const insane: { [k: number]: any } = []; insane[1] = first_map; insane[2] = second_map; return Q.resolve(insane); } - testMulti(arg0: any, arg1: number, arg2: Int64, 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.string_thing = "Hello2"; hello.byte_thing = arg0; hello.i32_thing = arg1; hello.i64_thing = arg2; return Q.resolve(hello); } testException(arg: string): Q.IPromise { - if (arg === 'Xception') { + if (arg === "Xception") { var x = new ttypes.Xception(); x.errorCode = 1001; x.message = arg; throw x; - } else if (arg === 'TException') { + } else if (arg === "TException") { throw new Thrift.TException(arg); } else { return Q.resolve(); } } testMultiException(arg0: string, arg1: string) { - if (arg0 === ('Xception')) { + if (arg0 === "Xception") { var x = new ttypes.Xception(); x.errorCode = 1001; - x.message = 'This is an Xception'; + x.message = "This is an Xception"; throw x; - } else if (arg0 === ('Xception2')) { + } else if (arg0 === "Xception2") { var x2 = new ttypes.Xception2(); x2.errorCode = 2002; x2.struct_thing = new ttypes.Xtruct(); - x2.struct_thing.string_thing = 'This is an Xception2'; + x2.struct_thing.string_thing = "This is an Xception2"; throw x2; } @@ -101,8 +107,7 @@ export class SyncThriftTestHandler { res.string_thing = arg1; return Q.resolve(res); } - testOneway(sleepFor: number) { - } + testOneway(sleepFor: number) {} testString(thing: string) { return Q.resolve(thing); @@ -131,10 +136,10 @@ export class SyncThriftTestHandler { testNest(thing: ttypes.Xtruct2) { return Q.resolve(thing); } - testMap(thing: { [k: number]: number; }) { + testMap(thing: { [k: number]: number }) { return Q.resolve(thing); } - testStringMap(thing: { [k: string]: string; }) { + testStringMap(thing: { [k: string]: string }) { return Q.resolve(thing); } testSet(thing: number[]) { @@ -161,13 +166,16 @@ export class AsyncThriftTestHandler { callback(undefined); return Q.resolve(); } - testMapMap(hello: number, - callback: (err: any, result: { [k: number]: { [k: number]: number; }; }) => void): - Q.IPromise<{ [k: number]: { [k: number]: number; }; }> { - - var mapmap: {[key: number]: {[key: number]: number; }} = []; - var pos: {[key: number]: number; } = []; - var neg: {[key: number]: number; } = []; + testMapMap( + hello: number, + callback: ( + err: any, + result: { [k: number]: { [k: number]: number } }, + ) => void, + ): Q.IPromise<{ [k: number]: { [k: number]: number } }> { + var mapmap: { [key: number]: { [key: number]: number } } = []; + var pos: { [key: number]: number } = []; + var neg: { [key: number]: number } = []; for (var i = 1; i < 5; i++) { pos[i] = i; neg[-i] = -i; @@ -178,54 +186,69 @@ export class AsyncThriftTestHandler { callback(null, mapmap); return Q.resolve(); } - testInsanity(argument: ttypes.Insanity, callback?: (err: any, result: { [k: number]: any; }) => void): Q.IPromise<{ [k: number]: any; }> { - const first_map: { [k: number]: any; } = []; - const second_map: { [k: number]: any; } = []; - + testInsanity( + argument: ttypes.Insanity, + callback?: (err: any, result: { [k: number]: any }) => void, + ): Q.IPromise<{ [k: number]: any }> { + const first_map: { [k: number]: any } = []; + const second_map: { [k: number]: any } = []; + first_map[ttypes.Numberz.TWO] = argument; first_map[ttypes.Numberz.THREE] = argument; - + const looney = new ttypes.Insanity(); second_map[ttypes.Numberz.SIX] = looney; - - const insane: { [k: number]: any; } = []; + + const insane: { [k: number]: any } = []; insane[1] = first_map; insane[2] = second_map; - if (callback !== undefined){ + if (callback !== undefined) { callback(null, insane); } return Q.resolve(); } - testMulti(arg0: any, arg1: number, arg2: Int64, arg3: { [k: number]: string; }, arg4: ttypes.Numberz, arg5: number, result: Function): Q.IPromise { + testMulti( + arg0: any, + arg1: number, + arg2: Int64, + arg3: { [k: number]: string }, + arg4: ttypes.Numberz, + arg5: number, + result: Function, + ): Q.IPromise { var hello = this.syncHandler.testMulti(arg0, arg1, arg2, arg3, arg4, arg5); - hello.then(hello => result(null, hello)); + hello.then((hello) => result(null, hello)); return Q.resolve(); } testException(arg: string, result: (err: any) => void): Q.IPromise { - if (arg === 'Xception') { + if (arg === "Xception") { var x = new ttypes.Xception(); x.errorCode = 1001; x.message = arg; result(x); - } else if (arg === 'TException') { + } else if (arg === "TException") { result(new Thrift.TException(arg)); } else { result(null); } return Q.resolve(); } - testMultiException(arg0: string, arg1: string, result: (err: any, res?: ttypes.Xtruct) => void): Q.IPromise { - if (arg0 === ('Xception')) { + testMultiException( + arg0: string, + arg1: string, + result: (err: any, res?: ttypes.Xtruct) => void, + ): Q.IPromise { + if (arg0 === "Xception") { var x = new ttypes.Xception(); x.errorCode = 1001; - x.message = 'This is an Xception'; + x.message = "This is an Xception"; result(x); - } else if (arg0 === ('Xception2')) { + } else if (arg0 === "Xception2") { var x2 = new ttypes.Xception2(); x2.errorCode = 2002; x2.struct_thing = new ttypes.Xtruct(); - x2.struct_thing.string_thing = 'This is an Xception2'; + x2.struct_thing.string_thing = "This is an Xception2"; result(x2); } else { var res = new ttypes.Xtruct(); @@ -237,63 +260,108 @@ export class AsyncThriftTestHandler { testOneway(sleepFor: number, result: Function) { this.syncHandler.testOneway(sleepFor); } - testString(thing: string, callback: (err: any, result: string) => void): Q.IPromise { + testString( + thing: string, + callback: (err: any, result: string) => void, + ): Q.IPromise { callback(null, thing); return Q.resolve(); } - testByte(thing: number, callback: (err: any, result: number) => void): Q.IPromise { + testByte( + thing: number, + callback: (err: any, result: number) => void, + ): Q.IPromise { callback(null, thing); return Q.resolve(); } - testBool(thing: boolean, callback: (err: any, result: boolean) => void ): Q.IPromise { + testBool( + thing: boolean, + callback: (err: any, result: boolean) => void, + ): Q.IPromise { callback(null, thing); return Q.resolve(); } - testI32(thing: number, callback: (err: any, result: number) => void): Q.IPromise { + testI32( + thing: number, + callback: (err: any, result: number) => void, + ): Q.IPromise { callback(null, thing); return Q.resolve(); } - testI64(thing: number, callback: (err: any, result: number) => void): Q.IPromise { + testI64( + thing: number, + callback: (err: any, result: number) => void, + ): Q.IPromise { callback(null, thing); return Q.resolve(); } - testDouble(thing: number, callback: (err: any, result: number) => void): Q.IPromise { + testDouble( + thing: number, + callback: (err: any, result: number) => void, + ): Q.IPromise { callback(null, thing); return Q.resolve(); } - testBinary(thing: Buffer, callback: (err: any, result: Buffer) => void): Q.IPromise { + testBinary( + thing: Buffer, + callback: (err: any, result: Buffer) => void, + ): Q.IPromise { callback(null, thing); return Q.resolve(); } - testStruct(thing: ttypes.Xtruct, callback: (err: any, result: ttypes.Xtruct) => void): Q.IPromise { + testStruct( + thing: ttypes.Xtruct, + callback: (err: any, result: ttypes.Xtruct) => void, + ): Q.IPromise { callback(null, thing); return Q.resolve(); } - testNest(thing: ttypes.Xtruct2, callback: (err: any, result: ttypes.Xtruct2) => void): Q.IPromise { + testNest( + thing: ttypes.Xtruct2, + callback: (err: any, result: ttypes.Xtruct2) => void, + ): Q.IPromise { callback(null, thing); return Q.resolve(); } - testMap(thing: { [k: number]: number; }, callback: (err: any, result: { [k: number]: number; }) => void): Q.IPromise<{ [k: number]: number; }> { + testMap( + thing: { [k: number]: number }, + callback: (err: any, result: { [k: number]: number }) => void, + ): Q.IPromise<{ [k: number]: number }> { callback(null, thing); return Q.resolve(); } - testStringMap(thing: { [k: string]: string; }, callback: (err: any, result: { [k: string]: string; }) => void): Q.IPromise<{ [k: string]: string; }> { + testStringMap( + thing: { [k: string]: string }, + callback: (err: any, result: { [k: string]: string }) => void, + ): Q.IPromise<{ [k: string]: string }> { callback(null, thing); return Q.resolve(); } - testSet(thing: number[], callback: (err: any, result: number[]) => void): Q.IPromise { + testSet( + thing: number[], + callback: (err: any, result: number[]) => void, + ): Q.IPromise { callback(null, thing); return Q.resolve(); } - testList(thing: number[], callback: (err: any, result: number[]) => void): Q.IPromise { + testList( + thing: number[], + callback: (err: any, result: number[]) => void, + ): Q.IPromise { callback(null, thing); return Q.resolve(); } - testEnum(thing: ttypes.Numberz, callback: (err: any, result: ttypes.Numberz) => void): Q.IPromise { + testEnum( + thing: ttypes.Numberz, + callback: (err: any, result: ttypes.Numberz) => void, + ): Q.IPromise { callback(null, thing); return Q.resolve(); } - testTypedef(thing: number, callback: (err: any, result: number) => void): Q.IPromise { + testTypedef( + thing: number, + callback: (err: any, result: number) => void, + ): Q.IPromise { callback(null, thing); return Q.resolve(); } diff --git a/lib/ocaml/_oasis b/lib/ocaml/_oasis index be1ce1265b9..bc01addfe3c 100644 --- a/lib/ocaml/_oasis +++ b/lib/ocaml/_oasis @@ -1,5 +1,5 @@ Name: libthrift-ocaml -Version: 0.20.0 +Version: 0.22.0 OASISFormat: 0.3 Synopsis: OCaml bindings for the Apache Thrift RPC system Authors: Apache Thrift Developers diff --git a/lib/perl/Makefile.am b/lib/perl/Makefile.am index 8b72436c500..9d762b41018 100644 --- a/lib/perl/Makefile.am +++ b/lib/perl/Makefile.am @@ -36,6 +36,9 @@ clean-local: $(RM) Makefile-perl.mk.old $(RM) -r gen-perl gen-perl2 +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ coding_standards.md \ build-cpan-dist.sh \ diff --git a/lib/perl/lib/Thrift.pm b/lib/perl/lib/Thrift.pm index 4b5f781e09f..995131eccd8 100644 --- a/lib/perl/lib/Thrift.pm +++ b/lib/perl/lib/Thrift.pm @@ -31,6 +31,6 @@ use warnings; # package Thrift; -use version 0.77; our $VERSION = version->declare("v0.20.0"); +use version 0.77; our $VERSION = version->declare("v0.22.0"); 1; diff --git a/lib/perl/t/Makefile.am b/lib/perl/t/Makefile.am index de03971869f..7e9d8a0b987 100644 --- a/lib/perl/t/Makefile.am +++ b/lib/perl/t/Makefile.am @@ -17,4 +17,7 @@ # under the License. # +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = memory_buffer.t processor.t multiplex.t diff --git a/lib/php/Makefile.am b/lib/php/Makefile.am index 91944c48164..ece8d244574 100644 --- a/lib/php/Makefile.am +++ b/lib/php/Makefile.am @@ -134,6 +134,8 @@ phptype_DATA = \ clean-local: if [ -f src/ext/thrift_protocol/Makefile ]; then cd src/ext/thrift_protocol/ && $(MAKE) clean; fi +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am EXTRA_DIST = \ lib \ @@ -148,19 +150,10 @@ EXTRA_DIST = \ src/TStringUtils.php \ coding_standards.md \ thrift_protocol.ini \ + phpunit.xml \ README.apache.md \ README.md \ - test/Fixtures.php \ - test/TestValidators.thrift \ - test/JsonSerialize/JsonSerializeTest.php \ - test/Protocol/BinarySerializerTest.php \ - test/Protocol/TJSONProtocolFixtures.php \ - test/Protocol/TJSONProtocolTest.php \ - test/Protocol/TSimpleJSONProtocolFixtures.php \ - test/Protocol/TSimpleJSONProtocolTest.php \ - test/Validator/BaseValidatorTest.php \ - test/Validator/ValidatorTest.php \ - test/Validator/ValidatorTestOop.php + test MAINTAINERCLEANFILES = \ diff --git a/lib/php/README.apache.md b/lib/php/README.apache.md index 5e925897596..2fae257afb5 100644 --- a/lib/php/README.apache.md +++ b/lib/php/README.apache.md @@ -29,7 +29,7 @@ you must use a THttpClient transport. Sample Code =========== - +```php open(); $processor->process($protocol, $protocol); $transport->close(); +``` diff --git a/lib/php/README.md b/lib/php/README.md index e7144fe444e..4bbc9675559 100644 --- a/lib/php/README.md +++ b/lib/php/README.md @@ -21,7 +21,7 @@ under the License. # Using Thrift with PHP -Thrift requires PHP 5. Thrift makes as few assumptions about your PHP +Thrift requires PHP 7.1 Thrift makes as few assumptions about your PHP environment as possible while trying to make some more advanced PHP features (i.e. APCu cacheing using asbolute path URLs) as simple as possible. diff --git a/lib/php/lib/Base/TBase.php b/lib/php/lib/Base/TBase.php index c61b631af60..d946665ecdc 100644 --- a/lib/php/lib/Base/TBase.php +++ b/lib/php/lib/Base/TBase.php @@ -31,6 +31,7 @@ * of PHP. Note that code is intentionally duplicated in here to avoid making * function calls for every field or member of a container.. */ +#[\AllowDynamicProperties] abstract class TBase { public static $tmethod = array( diff --git a/lib/php/lib/ClassLoader/ThriftClassLoader.php b/lib/php/lib/ClassLoader/ThriftClassLoader.php index e4b4a17c0c4..c1da4cb732b 100644 --- a/lib/php/lib/ClassLoader/ThriftClassLoader.php +++ b/lib/php/lib/ClassLoader/ThriftClassLoader.php @@ -1,4 +1,5 @@ apcu && ($file = $this->findFileInApcu($class))) or - ($file = $this->findFile($class)) + if ( + (true === $this->apcu && ($file = $this->findFileInApcu($class))) + || ($file = $this->findFile($class)) ) { require_once $file; } @@ -166,6 +168,7 @@ public function findFile($class) // Ignore wrong call if (count($m) <= 1) { + #HOW TO TEST THIS? HOW TEST CASE SHOULD LOOK LIKE? return; } @@ -183,8 +186,9 @@ public function findFile($class) * Available in service: Interface, Client, Processor, Rest * And every service methods (_.+) */ - if (0 === preg_match('#(.+)(if|client|processor|rest)$#i', $class, $n) and - 0 === preg_match('#(.+)_[a-z0-9]+_(args|result)$#i', $class, $n) + if ( + 0 === preg_match('#(.+)(if|client|processor|rest)$#i', $class, $n) + && 0 === preg_match('#(.+)_[a-z0-9]+_(args|result)$#i', $class, $n) ) { $className = 'Types'; } else { diff --git a/lib/php/lib/Exception/TException.php b/lib/php/lib/Exception/TException.php index 228d761e960..168688c665c 100644 --- a/lib/php/lib/Exception/TException.php +++ b/lib/php/lib/Exception/TException.php @@ -38,6 +38,7 @@ * @param mixed $p1 Message (string) or type-spec (array) * @param mixed $p2 Code (integer) or values (array) */ +#[\AllowDynamicProperties] class TException extends \Exception { public function __construct($p1 = null, $p2 = 0) diff --git a/lib/php/lib/Factory/TBinaryProtocolFactory.php b/lib/php/lib/Factory/TBinaryProtocolFactory.php index 2519183df22..fc02d7169aa 100644 --- a/lib/php/lib/Factory/TBinaryProtocolFactory.php +++ b/lib/php/lib/Factory/TBinaryProtocolFactory.php @@ -1,4 +1,5 @@ strictRead_ = $strictRead; $this->strictWrite_ = $strictWrite; } + /** + * @param TTransport $trans + * @return TBinaryProtocol + */ public function getProtocol($trans) { return new TBinaryProtocol($trans, $this->strictRead_, $this->strictWrite_); diff --git a/lib/php/lib/Factory/TCompactProtocolFactory.php b/lib/php/lib/Factory/TCompactProtocolFactory.php index 11fb8ff3369..9171f7b6f02 100644 --- a/lib/php/lib/Factory/TCompactProtocolFactory.php +++ b/lib/php/lib/Factory/TCompactProtocolFactory.php @@ -1,4 +1,5 @@ reader_ = new LookaheadReader($this); } - private $tmpbuf_ = array(4); - public function readJSONSyntaxChar($b) { $ch = $this->reader_->read(); @@ -197,68 +196,6 @@ public function readJSONSyntaxChar($b) } } - private function hexVal($s) - { - for ($i = 0; $i < strlen($s); $i++) { - $ch = substr($s, $i, 1); - - if (!($ch >= "a" && $ch <= "f") && !($ch >= "0" && $ch <= "9")) { - throw new TProtocolException("Expected hex character " . $ch, TProtocolException::INVALID_DATA); - } - } - - return hexdec($s); - } - - private function hexChar($val) - { - return dechex($val); - } - - private function hasJSONUnescapedUnicode() - { - if (PHP_MAJOR_VERSION > 5 || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 4)) { - return true; - } - - return false; - } - - private function unescapedUnicode($str) - { - if ($this->hasJSONUnescapedUnicode()) { - return json_encode($str, JSON_UNESCAPED_UNICODE); - } - - $json = json_encode($str); - - /* - * Unescaped character outside the Basic Multilingual Plane - * High surrogate: 0xD800 - 0xDBFF - * Low surrogate: 0xDC00 - 0xDFFF - */ - $json = preg_replace_callback( - '/\\\\u(d[89ab][0-9a-f]{2})\\\\u(d[cdef][0-9a-f]{2})/i', - function ($matches) { - return mb_convert_encoding(pack('H*', $matches[1] . $matches[2]), 'UTF-8', 'UTF-16BE'); - }, - $json - ); - - /* - * Unescaped characters within the Basic Multilingual Plane - */ - $json = preg_replace_callback( - '/\\\\u([0-9a-f]{4})/i', - function ($matches) { - return mb_convert_encoding(pack('H*', $matches[1]), 'UTF-8', 'UTF-16BE'); - }, - $json - ); - - return $json; - } - private function writeJSONString($b) { $this->context_->write(); @@ -267,7 +204,7 @@ private function writeJSONString($b) $this->trans_->write(self::QUOTE); } - $this->trans_->write($this->unescapedUnicode($b)); + $this->trans_->write(json_encode($b, JSON_UNESCAPED_UNICODE)); if (is_numeric($b) && $this->context_->escapeNum()) { $this->trans_->write(self::QUOTE); @@ -297,6 +234,7 @@ private function writeJSONDouble($num) $this->trans_->write(self::QUOTE); } + #TODO add compatibility with NAN and INF $this->trans_->write(json_encode($num)); if ($this->context_->escapeNum()) { @@ -304,14 +242,6 @@ private function writeJSONDouble($num) } } - private function writeJSONBase64($data) - { - $this->context_->write(); - $this->trans_->write(self::QUOTE); - $this->trans_->write(json_encode(base64_encode($data))); - $this->trans_->write(self::QUOTE); - } - private function writeJSONObjectStart() { $this->context_->write(); @@ -481,18 +411,6 @@ private function readJSONDouble() } } - private function readJSONBase64() - { - $arr = $this->readJSONString(false); - $data = base64_decode($arr, true); - - if ($data === false) { - throw new TProtocolException("Invalid base64 data " . $arr, TProtocolException::INVALID_DATA); - } - - return $data; - } - private function readJSONObjectStart() { $this->context_->read(); diff --git a/lib/php/lib/Protocol/TProtocol.php b/lib/php/lib/Protocol/TProtocol.php index f7b581f7bef..0de2cf5d42a 100644 --- a/lib/php/lib/Protocol/TProtocol.php +++ b/lib/php/lib/Protocol/TProtocol.php @@ -181,7 +181,7 @@ abstract public function readString(&$str); * The skip function is a utility to parse over unrecognized date without * causing corruption. * - * @param TType $type What type is it + * @param int $type What type is it (defined in TType::class) */ public function skip($type) { diff --git a/lib/php/lib/Protocol/TSimpleJSONProtocol.php b/lib/php/lib/Protocol/TSimpleJSONProtocol.php index 1cf1f640745..22f17423bc4 100644 --- a/lib/php/lib/Protocol/TSimpleJSONProtocol.php +++ b/lib/php/lib/Protocol/TSimpleJSONProtocol.php @@ -115,6 +115,7 @@ private function writeJSONDouble($num) $this->trans_->write(self::QUOTE); } + #TODO add compatibility with NAN and INF $this->trans_->write(json_encode((float)$num)); if ($isMapKey) { diff --git a/lib/php/lib/Server/TSSLServerSocket.php b/lib/php/lib/Server/TSSLServerSocket.php index ac589b76b78..e3778972318 100644 --- a/lib/php/lib/Server/TSSLServerSocket.php +++ b/lib/php/lib/Server/TSSLServerSocket.php @@ -49,6 +49,10 @@ public function __construct($host = 'localhost', $port = 9090, $context = null) { $ssl_host = $this->getSSLHost($host); parent::__construct($ssl_host, $port); + // Initialize a stream context if not provided + if ($context === null) { + $context = stream_context_create(); + } $this->context_ = $context; } diff --git a/lib/php/lib/Server/TServerTransport.php b/lib/php/lib/Server/TServerTransport.php index 15a27afa8ad..82ee752684b 100644 --- a/lib/php/lib/Server/TServerTransport.php +++ b/lib/php/lib/Server/TServerTransport.php @@ -3,6 +3,7 @@ namespace Thrift\Server; use Thrift\Exception\TTransportException; +use Thrift\Transport\TTransport; /** * Generic class for Server agent. diff --git a/lib/php/lib/StringFunc/Core.php b/lib/php/lib/StringFunc/Core.php index 376e437ff7f..45fb0fe03cf 100644 --- a/lib/php/lib/StringFunc/Core.php +++ b/lib/php/lib/StringFunc/Core.php @@ -1,4 +1,5 @@ scheme_ . "://" . $host . $this->uri_; $headers = array(); - $defaultHeaders = array('Accept' => 'application/x-thrift', + $defaultHeaders = array( + 'Accept' => 'application/x-thrift', 'Content-Type' => 'application/x-thrift', - 'Content-Length' => TStringFuncFactory::create()->strlen($this->request_)); + 'Content-Length' => TStringFuncFactory::create()->strlen($this->request_) + ); foreach (array_merge($defaultHeaders, $this->headers_) as $key => $value) { $headers[] = "$key: $value"; } @@ -292,10 +294,11 @@ public static function closeCurlHandle() { try { if (self::$curlHandle) { - curl_close(self::$curlHandle); + curl_close(self::$curlHandle); #This function has no effect. Prior to PHP 8.0.0, this function was used to close the resource. self::$curlHandle = null; } } catch (\Exception $x) { + #it's not possible to throw an exception by calling a function that has no effect error_log('There was an error closing the curl handle: ' . $x->getMessage()); } } diff --git a/lib/php/lib/Transport/THttpClient.php b/lib/php/lib/Transport/THttpClient.php index 4d6be32fed2..0f767f44330 100644 --- a/lib/php/lib/Transport/THttpClient.php +++ b/lib/php/lib/Transport/THttpClient.php @@ -1,4 +1,5 @@ host_ . ($this->port_ != 80 ? ':' . $this->port_ : ''); $headers = array(); - $defaultHeaders = array('Host' => $host, + $defaultHeaders = array( + 'Host' => $host, 'Accept' => 'application/x-thrift', 'User-Agent' => 'PHP/THttpClient', 'Content-Type' => 'application/x-thrift', - 'Content-Length' => TStringFuncFactory::create()->strlen($this->buf_)); + 'Content-Length' => TStringFuncFactory::create()->strlen($this->buf_) + ); + foreach (array_merge($defaultHeaders, $this->headers_) as $key => $value) { $headers[] = "$key: $value"; } @@ -225,10 +229,12 @@ public function flush() $baseHttpOptions = isset($options["http"]) ? $options["http"] : array(); - $httpOptions = $baseHttpOptions + array('method' => 'POST', + $httpOptions = $baseHttpOptions + array( + 'method' => 'POST', 'header' => implode("\r\n", $headers), 'max_redirects' => 1, - 'content' => $this->buf_); + 'content' => $this->buf_ + ); if ($this->timeout_ > 0) { $httpOptions['timeout'] = $this->timeout_; } diff --git a/lib/php/lib/Transport/TMemoryBuffer.php b/lib/php/lib/Transport/TMemoryBuffer.php index fee03a2a4b4..e5da9dab2c9 100644 --- a/lib/php/lib/Transport/TMemoryBuffer.php +++ b/lib/php/lib/Transport/TMemoryBuffer.php @@ -1,4 +1,5 @@ buf_ = $buf; } - protected $buf_ = ''; - public function isOpen() { return true; diff --git a/lib/php/lib/Transport/TPhpStream.php b/lib/php/lib/Transport/TPhpStream.php index 42823ff3372..2350b96f065 100644 --- a/lib/php/lib/Transport/TPhpStream.php +++ b/lib/php/lib/Transport/TPhpStream.php @@ -1,4 +1,5 @@ read_) { - $this->inStream_ = @fopen(self::inStreamName(), 'r'); + $this->inStream_ = @fopen($this->inStreamName(), 'r'); if (!is_resource($this->inStream_)) { throw new TException('TPhpStream: Could not open php://input'); } @@ -113,7 +114,7 @@ public function flush() @fflush($this->outStream_); } - private static function inStreamName() + private function inStreamName() { if (php_sapi_name() == 'cli') { return 'php://stdin'; diff --git a/lib/php/lib/Transport/TSSLSocket.php b/lib/php/lib/Transport/TSSLSocket.php index b4a0adb5430..16956e7d9b1 100644 --- a/lib/php/lib/Transport/TSSLSocket.php +++ b/lib/php/lib/Transport/TSSLSocket.php @@ -36,7 +36,7 @@ class TSSLSocket extends TSocket /** * Remote port * - * @var resource + * @var null|resource */ protected $context_ = null; @@ -57,6 +57,10 @@ public function __construct( ) { $this->host_ = $this->getSSLHost($host); $this->port_ = $port; + // Initialize a stream context if not provided + if ($context === null) { + $context = stream_context_create(); + } $this->context_ = $context; $this->debugHandler_ = $debugHandler ? $debugHandler : 'error_log'; } @@ -87,7 +91,8 @@ public function open() throw new TTransportException('Socket already connected', TTransportException::ALREADY_OPEN); } - if (empty($this->host_)) { + $host = parse_url($this->host_, PHP_URL_HOST); + if (empty($host)) { throw new TTransportException('Cannot open null host', TTransportException::NOT_OPEN); } diff --git a/lib/php/lib/Transport/TSocket.php b/lib/php/lib/Transport/TSocket.php index 8fe60fdaae7..c220a8b066b 100644 --- a/lib/php/lib/Transport/TSocket.php +++ b/lib/php/lib/Transport/TSocket.php @@ -218,7 +218,7 @@ public function open() throw new TTransportException('Cannot open null host', TTransportException::NOT_OPEN); } - if ($this->port_ <= 0) { + if ($this->port_ <= 0 && strpos($this->host_, 'unix://') !== 0) { throw new TTransportException('Cannot open without port', TTransportException::NOT_OPEN); } @@ -252,8 +252,10 @@ public function open() if (function_exists('socket_import_stream') && function_exists('socket_set_option')) { // warnings silenced due to bug https://bugs.php.net/bug.php?id=70939 - $socket = @socket_import_stream($this->handle_); - @socket_set_option($socket, SOL_TCP, TCP_NODELAY, 1); + $socket = socket_import_stream($this->handle_); + if ($socket !== false) { + @socket_set_option($socket, SOL_TCP, TCP_NODELAY, 1); + } } } diff --git a/lib/php/lib/Transport/TSocketPool.php b/lib/php/lib/Transport/TSocketPool.php index 307885f507a..312e023c60a 100644 --- a/lib/php/lib/Transport/TSocketPool.php +++ b/lib/php/lib/Transport/TSocketPool.php @@ -1,4 +1,5 @@ $host) { - $this->servers_ [] = array('host' => $host, - 'port' => $ports[$key]); + $this->servers_ [] = array( + 'host' => $host, + 'port' => $ports[$key] + ); } + + $this->useApcuCache = function_exists('apcu_fetch'); } /** @@ -206,7 +199,7 @@ public function open() $failtimeKey = 'thrift_failtime:' . $host . ':' . $port . '~'; // Cache miss? Assume it's OK - $lastFailtime = apcu_fetch($failtimeKey); + $lastFailtime = $this->apcuFetch($failtimeKey); if ($lastFailtime === false) { $lastFailtime = 0; } @@ -251,7 +244,7 @@ public function open() // Only clear the failure counts if required to do so if ($lastFailtime > 0) { - apcu_store($failtimeKey, 0); + $this->apcuStore($failtimeKey, 0); } // Successful connection, return now @@ -265,7 +258,7 @@ public function open() $consecfailsKey = 'thrift_consecfails:' . $host . ':' . $port . '~'; // Ignore cache misses - $consecfails = apcu_fetch($consecfailsKey); + $consecfails = $this->apcuFetch($consecfailsKey); if ($consecfails === false) { $consecfails = 0; } @@ -284,12 +277,12 @@ public function open() ); } // Store the failure time - apcu_store($failtimeKey, time()); + $this->apcuStore($failtimeKey, time()); // Clear the count of consecutive failures - apcu_store($consecfailsKey, 0); + $this->apcuStore($consecfailsKey, 0); } else { - apcu_store($consecfailsKey, $consecfails); + $this->apcuStore($consecfailsKey, $consecfails); } } } @@ -307,4 +300,20 @@ public function open() } throw new TException($error); } + + /** + * This library makes use of APCu cache to make hosts as down in a web + * environment. If you are running from the CLI or on a system without APCu + * installed, then these null functions will step in and act like cache + * misses. + */ + private function apcuFetch($key, &$success = null) + { + return $this->useApcuCache ? apcu_fetch($key, $success) : false; + } + + private function apcuStore($key, $var, $ttl = 0) + { + return $this->useApcuCache ? apcu_store($key, $var, $ttl) : false; + } } diff --git a/lib/php/lib/Type/TConstant.php b/lib/php/lib/Type/TConstant.php index 215da4a3d24..e16066c3381 100644 --- a/lib/php/lib/Type/TConstant.php +++ b/lib/php/lib/Type/TConstant.php @@ -43,7 +43,7 @@ public static function get($constant) { if (is_null(static::$$constant)) { static::$$constant = call_user_func( - sprintf('static::init_%s', $constant) + sprintf(static::class . '::init_%s', $constant) ); } diff --git a/lib/php/phpunit.xml b/lib/php/phpunit.xml new file mode 100644 index 00000000000..58e8f5dc2a9 --- /dev/null +++ b/lib/php/phpunit.xml @@ -0,0 +1,44 @@ + + + + + + ./lib + + + + + ./test/Unit + + + ./test/Integration + + + diff --git a/lib/php/src/Thrift.php b/lib/php/src/Thrift.php index 0364c90812f..1dbf64b0049 100644 --- a/lib/php/src/Thrift.php +++ b/lib/php/src/Thrift.php @@ -68,6 +68,7 @@ class TMessageType * @param mixed $p1 Message (string) or type-spec (array) * @param mixed $p2 Code (integer) or values (array) */ +#[\AllowDynamicProperties] class TException extends Exception { public function __construct($p1=null, $p2=0) @@ -419,6 +420,7 @@ protected function _write($class, $spec, $output) * of PHP. Note that code is intentionally duplicated in here to avoid making * function calls for every field or member of a container.. */ +#[\AllowDynamicProperties] abstract class TBase { static $tmethod = array(TType::BOOL => 'Bool', diff --git a/lib/php/test/Fixtures.php b/lib/php/test/Fixtures.php deleted file mode 100644 index fd57d831c5e..00000000000 --- a/lib/php/test/Fixtures.php +++ /dev/null @@ -1,194 +0,0 @@ -<><"; - - self::$testArgs['testString3'] = - "string that ends in double-backslash \\\\"; - - self::$testArgs['testUnicodeStringWithNonBMP'] = - "สวัสดี/𝒯"; - - self::$testArgs['testDouble'] = 3.1415926535898; - - // TODO: add testBinary() call - - self::$testArgs['testByte'] = 0x01; - - self::$testArgs['testI32'] = pow(2, 30); - - if (PHP_INT_SIZE == 8) { - self::$testArgs['testI64'] = pow(2, 60); - } else { - self::$testArgs['testI64'] = "1152921504606847000"; - } - - self::$testArgs['testStruct'] = - new Xtruct( - array( - 'string_thing' => 'worked', - 'byte_thing' => 0x01, - 'i32_thing' => pow(2, 30), - 'i64_thing' => self::$testArgs['testI64'] - ) - ); - - self::$testArgs['testNestNested'] = - new Xtruct( - array( - 'string_thing' => 'worked', - 'byte_thing' => 0x01, - 'i32_thing' => pow(2, 30), - 'i64_thing' => self::$testArgs['testI64'] - ) - ); - - self::$testArgs['testNest'] = - new Xtruct2( - array( - 'byte_thing' => 0x01, - 'struct_thing' => self::$testArgs['testNestNested'], - 'i32_thing' => pow(2, 15) - ) - ); - - self::$testArgs['testMap'] = - array( - 7 => 77, - 8 => 88, - 9 => 99 - ); - - self::$testArgs['testStringMap'] = - array( - "a" => "123", - "a b" => "with spaces ", - "same" => "same", - "0" => "numeric key", - "longValue" => self::$testArgs['testString1'], - self::$testArgs['testString1'] => "long key" - ); - - self::$testArgs['testSet'] = array(1 => true, 5 => true, 6 => true); - - self::$testArgs['testList'] = array(1, 2, 3); - - self::$testArgs['testEnum'] = Numberz::ONE; - - self::$testArgs['testTypedef'] = 69; - - self::$testArgs['testMapMapExpectedResult'] = - array( - 4 => array( - 1 => 1, - 2 => 2, - 3 => 3, - 4 => 4, - ), - -4 => array( - -4 => -4, - -3 => -3, - -2 => -2, - -1 => -1 - ) - ); - - // testInsanity ... takes a few steps to set up! - - $xtruct1 = - new Xtruct( - array( - 'string_thing' => 'Goodbye4', - 'byte_thing' => 4, - 'i32_thing' => 4, - 'i64_thing' => 4 - ) - ); - - $xtruct2 = - new Xtruct( - array( - 'string_thing' => 'Hello2', - 'byte_thing' => 2, - 'i32_thing' => 2, - 'i64_thing' => 2 - ) - ); - - $userMap = - array( - Numberz::FIVE => 5, - Numberz::EIGHT => 8 - ); - - $insanity2 = - new Insanity( - array( - 'userMap' => $userMap, - 'xtructs' => array($xtruct1, $xtruct2) - ) - ); - - $insanity3 = $insanity2; - - $insanity6 = - new Insanity( - array( - 'userMap' => null, - 'xtructs' => null - ) - ); - - self::$testArgs['testInsanityExpectedResult'] = - array( - "1" => array( - Numberz::TWO => $insanity2, - Numberz::THREE => $insanity3 - ), - "2" => array( - Numberz::SIX => $insanity6 - ) - ); - } -} diff --git a/lib/php/test/Validator/BaseValidatorTest.php b/lib/php/test/Integration/BaseValidatorTest.php similarity index 68% rename from lib/php/test/Validator/BaseValidatorTest.php rename to lib/php/test/Integration/BaseValidatorTest.php index 60290830e06..ae9d5844d2e 100644 --- a/lib/php/test/Validator/BaseValidatorTest.php +++ b/lib/php/test/Integration/BaseValidatorTest.php @@ -1,4 +1,5 @@ assertNoReadValidator('ThriftTest\EmptyStruct'); - $this->assertNoWriteValidator('ThriftTest\EmptyStruct'); + $this->assertNoReadValidator($this->getNsGlobal() . '\ThriftTest\EmptyStruct'); + $this->assertNoWriteValidator($this->getNsGlobal() . '\ThriftTest\EmptyStruct'); } public function testBonkValidator() { - $this->assertNoReadValidator('ThriftTest\Bonk'); - $this->assertHasWriteValidator('ThriftTest\Bonk'); + $this->assertNoReadValidator($this->getNsGlobal() . '\ThriftTest\Bonk'); + $this->assertHasWriteValidator($this->getNsGlobal() . '\ThriftTest\Bonk'); } public function testStructAValidator() { - $this->assertHasReadValidator('ThriftTest\StructA'); - $this->assertHasWriteValidator('ThriftTest\StructA'); + $this->assertHasReadValidator($this->getNsGlobal() . '\ThriftTest\StructA'); + $this->assertHasWriteValidator($this->getNsGlobal() . '\ThriftTest\StructA'); } public function testUnionOfStringsValidator() { - $this->assertNoWriteValidator('TestValidators\UnionOfStrings'); + $this->assertNoWriteValidator($this->getNsGlobal() . '\TestValidators\UnionOfStrings'); } public function testServiceResultValidator() { - $this->assertNoReadValidator('TestValidators\TestService_test_result'); - $this->assertNoWriteValidator('TestValidators\TestService_test_result'); + $this->assertNoReadValidator($this->getNsGlobal() . '\TestValidators\TestService_test_result'); + $this->assertNoWriteValidator($this->getNsGlobal() . '\TestValidators\TestService_test_result'); } public function testReadEmpty() { - $bonk = new \ThriftTest\Bonk(); + $className = $this->getNsGlobal() . '\ThriftTest\Bonk'; + $bonk = new $className(); $transport = new TMemoryBuffer("\000"); $protocol = new TBinaryProtocol($transport); $bonk->read($protocol); + $this->assertTrue(true); } public function testWriteEmpty() { - $bonk = new \ThriftTest\Bonk(); + $className = $this->getNsGlobal() . '\ThriftTest\Bonk'; + $bonk = new $className(); $transport = new TMemoryBuffer(); $protocol = new TBinaryProtocol($transport); try { $bonk->write($protocol); $this->fail('Bonk was able to write an empty object'); } catch (TProtocolException $e) { + $this->expectExceptionMessage('Required field Bonk.message is unset!'); + throw $e; } } public function testWriteWithMissingRequired() { // Check that we are not able to write StructA with a missing required field - $structa = new \ThriftTest\StructA(); + $className = $this->getNsGlobal() . '\ThriftTest\StructA'; + $structa = new $className(); $transport = new TMemoryBuffer(); $protocol = new TBinaryProtocol($transport); @@ -87,6 +96,8 @@ public function testWriteWithMissingRequired() $structa->write($protocol); $this->fail('StructA was able to write an empty object'); } catch (TProtocolException $e) { + $this->expectExceptionMessage('Required field StructA.s is unset!'); + throw $e; } } @@ -94,7 +105,8 @@ public function testReadStructA() { $transport = new TMemoryBuffer(base64_decode('CwABAAAAA2FiYwA=')); $protocol = new TBinaryProtocol($transport); - $structa = new \ThriftTest\StructA(); + $className = $this->getNsGlobal() . '\ThriftTest\StructA'; + $structa = new $className(); $structa->read($protocol); $this->assertEquals("abc", $structa->s); } @@ -103,7 +115,8 @@ public function testWriteStructA() { $transport = new TMemoryBuffer(); $protocol = new TBinaryProtocol($transport); - $structa = new \ThriftTest\StructA(); + $className = $this->getNsGlobal() . '\ThriftTest\StructA'; + $structa = new $className(); $structa->s = "abc"; $structa->write($protocol); $writeResult = base64_encode($transport->getBuffer()); @@ -114,6 +127,8 @@ protected static function assertHasReadValidator($class) { if (!static::hasReadValidator($class)) { static::fail($class . ' class should have a read validator'); + } else { + static::assertTrue(true); } } @@ -121,6 +136,8 @@ protected static function assertNoReadValidator($class) { if (static::hasReadValidator($class)) { static::fail($class . ' class should not have a write validator'); + } else { + static::assertTrue(true); } } @@ -128,6 +145,8 @@ protected static function assertHasWriteValidator($class) { if (!static::hasWriteValidator($class)) { static::fail($class . ' class should have a write validator'); + } else { + static::assertTrue(true); } } @@ -135,6 +154,8 @@ protected static function assertNoWriteValidator($class) { if (static::hasWriteValidator($class)) { static::fail($class . ' class should not have a write validator'); + } else { + static::assertTrue(true); } } diff --git a/lib/php/test/Integration/Lib/ClassLoader/ThriftClassLoaderTest.php b/lib/php/test/Integration/Lib/ClassLoader/ThriftClassLoaderTest.php new file mode 100644 index 00000000000..a43f5c68685 --- /dev/null +++ b/lib/php/test/Integration/Lib/ClassLoader/ThriftClassLoaderTest.php @@ -0,0 +1,139 @@ +getFunctionMock('Thrift\ClassLoader', 'apcu_fetch') + ->expects($useApcu ? $this->any() : $this->never()) + ->with($apcuPrefix . $class) + ->willReturn(false); + + $this->getFunctionMock('Thrift\ClassLoader', 'apcu_store') + ->expects($useApcu ? $this->any() : $this->never()) + ->with($apcuPrefix . $class, $this->anything()) + ->willReturn(true); + + $loader = new ThriftClassLoader($useApcu, $apcuPrefix); + foreach ($definitions as $namespace => $paths) { + $loader->registerDefinition($namespace, $paths); + } + $loader->register(); + + $loader->loadClass($class); + if ($checkInterfaceExist) { + $this->assertTrue(interface_exists($class, false), "->loadClass() loads '$class'"); + } else { + $this->assertTrue(class_exists($class, false), "->loadClass() loads '$class'"); + } + } + + public function registerDefinitionDataProvider() + { + yield 'loadType' => [ + 'definitions' => [ + 'Classmap' => __DIR__ . '/../../../Resources/packages/phpcm', + ], + 'class' => 'Classmap\ThriftTest\Xtruct', + ]; + yield 'loadInterface' => [ + 'definitions' => [ + 'Classmap' => __DIR__ . '/../../../Resources/packages/phpcm', + ], + 'class' => '\Classmap\ThriftTest\ThriftTestIf', + 'checkInterfaceExist' => true, + ]; + yield 'loadClient' => [ + 'definitions' => [ + 'Classmap' => __DIR__ . '/../../../Resources/packages/phpcm', + ], + 'class' => '\Classmap\ThriftTest\ThriftTestClient', + ]; + yield 'loadProcessor' => [ + 'definitions' => [ + 'Classmap' => __DIR__ . '/../../../Resources/packages/phpcm', + ], + 'class' => '\Classmap\ThriftTest\ThriftTestProcessor', + ]; + yield 'loadRest' => [ + 'definitions' => [ + 'Classmap' => __DIR__ . '/../../../Resources/packages/phpcm', + ], + 'class' => '\Classmap\ThriftTest\ThriftTestRest', + ]; + yield 'load_args' => [ + 'definitions' => [ + 'Classmap' => __DIR__ . '/../../../Resources/packages/phpcm', + ], + 'class' => '\Classmap\ThriftTest\ThriftTest_testVoid_args', + ]; + yield 'load_result' => [ + 'definitions' => [ + 'Classmap' => __DIR__ . '/../../../Resources/packages/phpcm', + ], + 'class' => '\Classmap\ThriftTest\ThriftTest_testVoid_result', + ]; + yield 'pathAsArray' => [ + 'definitions' => [ + 'Classmap' => [__DIR__ . '/../../../Resources/packages/phpcm'], + ], + 'class' => 'Classmap\ThriftTest\Xtruct', + ]; + yield 'severalDefinitions' => [ + 'definitions' => [ + 'Classmap\ThriftTest' => [__DIR__ . '/../../../Resources/packages/phpcm'], + 'Classmap\TestValidators' => [__DIR__ . '/../../../Resources/packages/phpcm'], + ], + 'class' => '\Classmap\TestValidators\TestServiceClient', + ]; + yield 'useApcu' => [ + 'definitions' => [ + 'Classmap\ThriftTest' => [__DIR__ . '/../../../Resources/packages/phpcm'], + 'Classmap\TestValidators' => [__DIR__ . '/../../../Resources/packages/phpcm'], + ], + 'class' => '\Classmap\TestValidators\TestServiceClient', + 'checkInterfaceExist' => false, + 'useApcu' => true, + 'apcuPrefix' => 'APCU_PREFIX', + ]; + } +} diff --git a/lib/php/test/Integration/Lib/Protocol/TJSONProtocolTest.php b/lib/php/test/Integration/Lib/Protocol/TJSONProtocolTest.php new file mode 100644 index 00000000000..515cbdb3419 --- /dev/null +++ b/lib/php/test/Integration/Lib/Protocol/TJSONProtocolTest.php @@ -0,0 +1,646 @@ +transport = new TMemoryBuffer(); + $this->protocol = new TJSONProtocol($this->transport); + $this->transport->open(); + } + + public function testMessageReadWrite() + { + $input = new TJSONProtocol(new TMemoryBuffer('[1,"testString",1,0,{"0":{"str":"successResponse"}}]')); + $service = new \Basic\ThriftTest\ThriftTestClient($input, $this->protocol); + $result = $service->testString('test'); + $this->assertSame('successResponse', $result); + } + + /** + * @dataProvider writeDataProvider + */ + public function testWrite( + $argsClassName, + $argsValues, + $expected + ) { + $args = new $argsClassName($argsValues); + $args->write($this->protocol); + + $actual = $this->transport->read(self::BUFFER_SIZE); + + $this->assertEquals($expected, $actual); + } + + public function writeDataProvider() + { + if (!is_dir(__DIR__ . '/../../../Resources/packages/php')) { + throw new \RuntimeException( + 'Before running Integration test suite, you must run the Thrift compiler against the ThriftTest.thrift file in the ./Resources directory.' + ); + } + + yield 'void' => [ + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testVoid_args::class, + 'argsValues' => [], + 'expected' => '{}', + ]; + yield 'bool true' => [ + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testBool_args::class, + 'argsValues' => [ + 'thing' => true, + ], + 'expected' => '{"1":{"tf":1}}', + ]; + yield 'bool false' => [ + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testBool_args::class, + 'argsValues' => [ + 'thing' => false, + ], + 'expected' => '{"1":{"tf":0}}', + ]; + yield 'string1' => [ + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testString_args::class, + 'argsValues' => [ + 'thing' => "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ú, 粵語", + ], + 'expected' => '{"1":{"str":"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ú, 粵語"}}', + ]; + yield 'string2' => [ + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testString_args::class, + 'argsValues' => [ + 'thing' => "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: !@#\$%&()(&%$#{}{}<><><", + ], + 'expected' => '{"1":{"str":"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: !@#$%&()(&%$#{}{}<><><"}}', + ]; + yield 'string3' => [ + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testString_args::class, + 'argsValues' => [ + 'thing' => "string that ends in double-backslash \\\\", + ], + 'expected' => '{"1":{"str":"string that ends in double-backslash \\\\\\\\"}}', + ]; + yield 'string4 testUnicodeStringWithNonBMP' => [ + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testString_args::class, + 'argsValues' => [ + 'thing' => "สวัสดี/𝒯", + ], + 'expected' => '{"1":{"str":"สวัสดี\/𝒯"}}', + ]; + yield 'double' => [ + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testDouble_args::class, + 'argsValues' => [ + 'thing' => 3.1415926535898, + ], + 'expected' => '{"1":{"dbl":3.1415926535898}}', + ]; + #TODO Should be fixed in future + yield 'double Nan' => [ + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testDouble_args::class, + 'argsValues' => [ + 'thing' => NAN, + ], + 'expected' => '{"1":{"dbl":}}', + ]; + #TODO Should be fixed in future + yield 'double Infinity' => [ + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testDouble_args::class, + 'argsValues' => [ + 'thing' => INF, + ], + 'expected' => '{"1":{"dbl":}}', + ]; + yield 'byte' => [ + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testByte_args::class, + 'argsValues' => [ + 'thing' => 0x01, + ], + 'expected' => '{"1":{"i8":1}}', + ]; + yield 'i32' => [ + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testI32_args::class, + 'argsValues' => [ + 'thing' => pow(2, 30), + ], + 'expected' => '{"1":{"i32":1073741824}}', + ]; + if (PHP_INT_SIZE == 8) { + yield 'i64_64Architecture' => [ + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testI64_args::class, + 'argsValues' => [ + 'thing' => pow(2, 60), + ], + 'expected' => '{"1":{"i64":' . pow(2, 60) . '}}', + ]; + yield 'struct_64Architecture' => [ + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testStruct_args::class, + 'argsValues' => [ + 'thing' => new Xtruct( + [ + 'string_thing' => 'worked', + 'byte_thing' => 0x01, + 'i32_thing' => pow(2, 30), + 'i64_thing' => pow(2, 60), + ] + ), + ], + 'expected' => '{"1":{"rec":{"1":{"str":"worked"},"4":{"i8":1},"9":{"i32":1073741824},"11":{"i64":' . pow(2, 60) . '}}}}', + ]; + yield 'nest_64Architecture' => [ + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testNest_args::class, + 'argsValues' => [ + 'thing' => new Xtruct2( + [ + 'byte_thing' => 0x01, + 'struct_thing' => new Xtruct( + [ + 'string_thing' => 'worked', + 'byte_thing' => 0x01, + 'i32_thing' => pow(2, 30), + 'i64_thing' => pow(2, 60), + ] + ), + 'i32_thing' => pow(2, 15), + ] + ), + ], + 'expected' => '{"1":{"rec":{"1":{"i8":1},"2":{"rec":{"1":{"str":"worked"},"4":{"i8":1},"9":{"i32":1073741824},"11":{"i64":' . pow(2, 60) . '}}},"3":{"i32":32768}}}}', + ]; + } else { + yield 'i64_32Architecture' => [ + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testI64_args::class, + 'argsValues' => [ + 'thing' => "1152921504606847000", + ], + 'expected' => '{"1":{"i64":1152921504606847000}}', + ]; + yield 'struct_32Architecture' => [ + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testStruct_args::class, + 'argsValues' => [ + 'thing' => new Xtruct( + [ + 'string_thing' => 'worked', + 'byte_thing' => 0x01, + 'i32_thing' => pow(2, 30), + 'i64_thing' => pow(2, 60), + ] + ), + ], + 'expected' => '{"1":{"rec":{"1":{"str":"worked"},"4":{"i8":1},"9":{"i32":1073741824},"11":{"i64":1152921504606847000}}}}', + ]; + yield 'nest_32Architecture' => [ + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testNest_args::class, + 'argsValues' => [ + 'thing' => new Xtruct2( + [ + 'byte_thing' => 0x01, + 'struct_thing' => new Xtruct( + [ + 'string_thing' => 'worked', + 'byte_thing' => 0x01, + 'i32_thing' => pow(2, 30), + 'i64_thing' => '1152921504606847000', + ] + ), + 'i32_thing' => pow(2, 15), + ] + ), + ], + 'expected' => '{"1":{"rec":{"1":{"i8":1},"2":{"rec":{"1":{"str":"worked"},"4":{"i8":1},"9":{"i32":1073741824},"11":{"i64":1152921504606847000}}},"3":{"i32":32768}}}}', + ]; + } + yield 'map' => [ + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testMap_args::class, + 'argsValues' => [ + 'thing' => [ + 7 => 77, + 8 => 88, + 9 => 99, + ], + ], + 'expected' => '{"1":{"map":["i32","i32",3,{"7":77,"8":88,"9":99}]}}', + ]; + yield 'stringMap' => [ + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testStringMap_args::class, + 'argsValues' => [ + 'thing' => [ + "a" => "123", + "a b" => "with spaces ", + "same" => "same", + "0" => "numeric key", + "longValue" => "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ú, 粵語", + "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ú, 粵語" => "long key", + ], + ], + 'expected' => '{"1":{"map":["str","str",6,{"a":"123","a b":"with spaces ","same":"same","0":"numeric key","longValue":"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ú, 粵語","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ú, 粵語":"long key"}]}}', + ]; + yield 'set' => [ + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testSet_args::class, + 'argsValues' => [ + 'thing' => [1 => true, 5 => true, 6 => true], + ], + 'expected' => '{"1":{"set":["i32",3,1,5,6]}}', + ]; + yield 'list' => [ + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testList_args::class, + 'argsValues' => [ + 'thing' => [1, 2, 3], + ], + 'expected' => '{"1":{"lst":["i32",3,1,2,3]}}', + ]; + yield 'enum' => [ + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testEnum_args::class, + 'argsValues' => [ + 'thing' => \Basic\ThriftTest\Numberz::SIX, + ], + 'expected' => '{"1":{"i32":6}}', + ]; + yield 'typedef' => [ + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testTypedef_args::class, + 'argsValues' => [ + 'thing' => 69, + ], + 'expected' => '{"1":{"i64":69}}', + ]; + } + + /** + * @dataProvider readDataProvider + */ + public function testRead( + $buffer, + $argsClassName, + $argsPropertyName, + $expectedValue, + $expectedResult + ): void { + $this->transport->write($buffer); + $args = new $argsClassName(); + $result = $args->read($this->protocol); + + $this->assertEquals($expectedResult, $result); + + if (is_null($argsPropertyName)) { + $this->assertNull($argsPropertyName); + } elseif (is_float($expectedValue) && is_nan($expectedValue)) { + $this->assertNan($args->{$argsPropertyName}); + } elseif (is_float($expectedValue) && is_infinite($expectedValue)) { + $this->assertEquals($expectedValue, $args->{$argsPropertyName}); + } else { + $this->assertEquals($expectedValue, $args->{$argsPropertyName}); + } + } + + public function readDataProvider() + { + yield 'void' => [ + 'buffer' => '{}', + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testVoid_args::class, + 'argsPropertyName' => null, + 'expectedValue' => null, + 'expectedResult' => 0, + ]; + yield 'bool true' => [ + 'buffer' => '{"1":{"tf":1}}', + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testBool_args::class, + 'argsPropertyName' => 'thing', + 'expectedValue' => true, + 'expectedResult' => 1, + ]; + yield 'bool false' => [ + 'buffer' => '{"1":{"tf":0}}', + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testBool_args::class, + 'argsPropertyName' => 'thing', + 'expectedValue' => false, + 'expectedResult' => 1, + ]; + yield 'string1' => [ + 'buffer' => '{"1":{"str":"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ú, 粵語"}}', + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testString_args::class, + 'argsPropertyName' => 'thing', + 'expectedValue' => "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ú, 粵語", + 'expectedResult' => 1, + ]; + yield 'string2' => [ + 'buffer' => '{"1":{"str":"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: !@#$%&()(&%$#{}{}<><><"}}', + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testString_args::class, + 'argsPropertyName' => 'thing', + 'expectedValue' => "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: !@#\$%&()(&%$#{}{}<><><", + 'expectedResult' => 1, + ]; + yield 'string3' => [ + 'buffer' => '{"1":{"str":"string that ends in double-backslash \\\\\\\\"}}', + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testString_args::class, + 'argsPropertyName' => 'thing', + 'expectedValue' => "string that ends in double-backslash \\\\", + 'expectedResult' => 1, + ]; + yield 'string4' => [ + 'buffer' => '{"1":{"str":"สวัสดี\/𝒯"}}', + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testString_args::class, + 'argsPropertyName' => 'thing', + 'expectedValue' => "สวัสดี/𝒯", + 'expectedResult' => 1, + ]; + yield 'double' => [ + 'buffer' => '{"1":{"dbl":3.1415926535898}}', + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testDouble_args::class, + 'argsPropertyName' => 'thing', + 'expectedValue' => 3.1415926535898, + 'expectedResult' => 1, + ]; + yield 'double Nan' => [ + 'buffer' => '{"1":{"dbl":"NaN"}}', + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testDouble_args::class, + 'argsPropertyName' => 'thing', + 'expectedValue' => NAN, + 'expectedResult' => 1, + ]; + yield 'double Infinity' => [ + 'buffer' => '{"1":{"dbl":"Infinity"}}', + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testDouble_args::class, + 'argsPropertyName' => 'thing', + 'expectedValue' => INF, + 'expectedResult' => 1, + ]; + yield 'byte' => [ + 'buffer' => '{"1":{"i8":1}}', + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testByte_args::class, + 'argsPropertyName' => 'thing', + 'expectedValue' => 0x01, + 'expectedResult' => 1, + ]; + yield 'i32' => [ + 'buffer' => '{"1":{"i32":1073741824}}', + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testI32_args::class, + 'argsPropertyName' => 'thing', + 'expectedValue' => pow(2, 30), + 'expectedResult' => 1, + ]; + if (PHP_INT_SIZE == 8) { + yield 'i64_64Architecture' => [ + 'buffer' => '{"1":{"i64":' . pow(2, 60) . '}}', + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testI64_args::class, + 'argsPropertyName' => 'thing', + 'expectedValue' => pow(2, 60), + 'expectedResult' => 1, + ]; + yield 'struct_64Architecture' => [ + 'buffer' => '{"1":{"rec":{"1":{"str":"worked"},"4":{"i8":1},"9":{"i32":1073741824},"11":{"i64":' . pow(2, 60) . '}}}}', + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testStruct_args::class, + 'argsPropertyName' => 'thing', + 'expectedValue' => new Xtruct( + array( + 'string_thing' => 'worked', + 'byte_thing' => 0x01, + 'i32_thing' => pow(2, 30), + 'i64_thing' => pow(2, 60), + ) + ), + 'expectedResult' => 4, + ]; + yield 'nest_64Architecture' => [ + 'buffer' => '{"1":{"rec":{"1":{"i8":1},"2":{"rec":{"1":{"str":"worked"},"4":{"i8":1},"9":{"i32":1073741824},"11":{"i64":' . pow(2, 60) . '}}},"3":{"i32":32768}}}}', + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testNest_args::class, + 'argsPropertyName' => 'thing', + 'expectedValue' => new Xtruct2( + array( + 'byte_thing' => 0x01, + 'struct_thing' => new Xtruct( + array( + 'string_thing' => 'worked', + 'byte_thing' => 0x01, + 'i32_thing' => pow(2, 30), + 'i64_thing' => pow(2, 60), + ) + ), + 'i32_thing' => pow(2, 15) + ) + ), + 'expectedResult' => 6, + ]; + } else { + yield 'i64_32Architecture' => [ + 'buffer' => '{"1":{"i64":1152921504606847000}}', + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testI64_args::class, + 'argsPropertyName' => 'thing', + 'expectedValue' => "1152921504606847000", + 'expectedResult' => 1, + ]; + yield 'struct_32Architecture' => [ + 'buffer' => '{"1":{"rec":{"1":{"str":"worked"},"4":{"i8":1},"9":{"i32":1073741824},"11":{"i64":1152921504606847000}}}}', + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testStruct_args::class, + 'expectedValue' => new Xtruct( + array( + 'string_thing' => 'worked', + 'byte_thing' => 0x01, + 'i32_thing' => pow(2, 30), + 'i64_thing' => "1152921504606847000", + ) + ), + 'expectedResult' => 4, + ]; + yield 'nest_32Architecture' => [ + 'buffer' => '{"1":{"rec":{"1":{"i8":1},"2":{"rec":{"1":{"str":"worked"},"4":{"i8":1},"9":{"i32":1073741824},"11":{"i64":1152921504606847000}}},"3":{"i32":32768}}}}', + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testNest_args::class, + 'argsPropertyName' => 'thing', + 'expectedValue' => new Xtruct2( + array( + 'byte_thing' => 0x01, + 'struct_thing' => new Xtruct( + array( + 'string_thing' => 'worked', + 'byte_thing' => 0x01, + 'i32_thing' => pow(2, 30), + 'i64_thing' => "1152921504606847000", + ) + ), + 'i32_thing' => pow(2, 15) + ) + ), + 'expectedResult' => 6, + ]; + } + yield 'map' => [ + 'buffer' => '{"1":{"map":["i32","i32",3,{"7":77,"8":88,"9":99}]}}', + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testMap_args::class, + 'argsPropertyName' => 'thing', + 'expectedValue' => [ + 7 => 77, + 8 => 88, + 9 => 99 + ], + 'expectedResult' => 6, + ]; + yield 'stringMap' => [ + 'buffer' => '{"1":{"map":["str","str",6,{"a":"123","a b":"with spaces ","same":"same","0":"numeric key","longValue":"Afrikaans, Alemannisch, Aragon\u00e9s, \u0627\u0644\u0639\u0631\u0628\u064a\u0629, \u0645\u0635\u0631\u0649, Asturianu, Aymar aru, Az\u0259rbaycan, \u0411\u0430\u0448\u04a1\u043e\u0440\u0442, Boarisch, \u017demait\u0117\u0161ka, \u0411\u0435\u043b\u0430\u0440\u0443\u0441\u043a\u0430\u044f, \u0411\u0435\u043b\u0430\u0440\u0443\u0441\u043a\u0430\u044f (\u0442\u0430\u0440\u0430\u0448\u043a\u0435\u0432\u0456\u0446\u0430), \u0411\u044a\u043b\u0433\u0430\u0440\u0441\u043a\u0438, Bamanankan, \u09ac\u09be\u0982\u09b2\u09be, Brezhoneg, Bosanski, Catal\u00e0, M\u00ecng-d\u0115\u0324ng-ng\u1e73\u0304, \u041d\u043e\u0445\u0447\u0438\u0439\u043d, Cebuano, \u13e3\u13b3\u13a9, \u010cesky, \u0421\u043b\u043e\u0432\u0463\u0301\u043d\u044c\u0441\u043a\u044a \/ \u2c14\u2c0e\u2c11\u2c02\u2c21\u2c10\u2c20\u2c14\u2c0d\u2c1f, \u0427\u04d1\u0432\u0430\u0448\u043b\u0430, Cymraeg, Dansk, Zazaki, \u078b\u07a8\u0788\u07ac\u0780\u07a8\u0784\u07a6\u0790\u07b0, \u0395\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ac, Emili\u00e0n e rumagn\u00f2l, English, Esperanto, Espa\u00f1ol, Eesti, Euskara, \u0641\u0627\u0631\u0633\u06cc, Suomi, V\u00f5ro, F\u00f8royskt, Fran\u00e7ais, Arpetan, Furlan, Frysk, Gaeilge, \u8d1b\u8a9e, G\u00e0idhlig, Galego, Ava\u00f1e\'\u1ebd, \u0a97\u0ac1\u0a9c\u0ab0\u0abe\u0aa4\u0ac0, Gaelg, \u05e2\u05d1\u05e8\u05d9\u05ea, \u0939\u093f\u0928\u094d\u0926\u0940, Fiji Hindi, Hrvatski, Krey\u00f2l ayisyen, Magyar, \u0540\u0561\u0575\u0565\u0580\u0565\u0576, Interlingua, Bahasa Indonesia, Ilokano, Ido, \u00cdslenska, Italiano, \u65e5\u672c\u8a9e, Lojban, Basa Jawa, \u10e5\u10d0\u10e0\u10d7\u10e3\u10da\u10d8, Kongo, Kalaallisut, \u0c95\u0ca8\u0ccd\u0ca8\u0ca1, \ud55c\uad6d\uc5b4, \u041a\u044a\u0430\u0440\u0430\u0447\u0430\u0439-\u041c\u0430\u043b\u043a\u044a\u0430\u0440, Ripoarisch, Kurd\u00ee, \u041a\u043e\u043c\u0438, Kernewek, \u041a\u044b\u0440\u0433\u044b\u0437\u0447\u0430, Latina, Ladino, L\u00ebtzebuergesch, Limburgs, Ling\u00e1la, \u0ea5\u0eb2\u0ea7, Lietuvi\u0173, Latvie\u0161u, Basa Banyumasan, Malagasy, \u041c\u0430\u043a\u0435\u0434\u043e\u043d\u0441\u043a\u0438, \u0d2e\u0d32\u0d2f\u0d3e\u0d33\u0d02, \u092e\u0930\u093e\u0920\u0940, Bahasa Melayu, \u0645\u0627\u0632\u0650\u0631\u0648\u0646\u06cc, Nnapulitano, Nedersaksisch, \u0928\u0947\u092a\u093e\u0932 \u092d\u093e\u0937\u093e, Nederlands, \u202aNorsk (nynorsk)\u202c, \u202aNorsk (bokm\u00e5l)\u202c, Nouormand, Din\u00e9 bizaad, Occitan, \u0418\u0440\u043e\u043d\u0430\u0443, Papiamentu, Deitsch, Norfuk \/ Pitkern, Polski, \u067e\u0646\u062c\u0627\u0628\u06cc, \u067e\u069a\u062a\u0648, Portugu\u00eas, Runa Simi, Rumantsch, Romani, Rom\u00e2n\u0103, \u0420\u0443\u0441\u0441\u043a\u0438\u0439, \u0421\u0430\u0445\u0430 \u0442\u044b\u043b\u0430, Sardu, Sicilianu, Scots, S\u00e1megiella, Simple English, Sloven\u010dina, Sloven\u0161\u010dina, \u0421\u0440\u043f\u0441\u043a\u0438 \/ Srpski, Seeltersk, Svenska, Kiswahili, \u0ba4\u0bae\u0bbf\u0bb4\u0bcd, \u0c24\u0c46\u0c32\u0c41\u0c17\u0c41, \u0422\u043e\u04b7\u0438\u043a\u04e3, \u0e44\u0e17\u0e22, T\u00fcrkmen\u00e7e, Tagalog, T\u00fcrk\u00e7e, \u0422\u0430\u0442\u0430\u0440\u0447\u0430\/Tatar\u00e7a, \u0423\u043a\u0440\u0430\u0457\u043d\u0441\u044c\u043a\u0430, \u0627\u0631\u062f\u0648, Ti\u1ebfng Vi\u1ec7t, Volap\u00fck, Walon, Winaray, \u5434\u8bed, isiXhosa, \u05d9\u05d9\u05b4\u05d3\u05d9\u05e9, Yor\u00f9b\u00e1, Ze\u00eauws, \u4e2d\u6587, B\u00e2n-l\u00e2m-g\u00fa, \u7cb5\u8a9e","Afrikaans, Alemannisch, Aragon\u00e9s, \u0627\u0644\u0639\u0631\u0628\u064a\u0629, \u0645\u0635\u0631\u0649, Asturianu, Aymar aru, Az\u0259rbaycan, \u0411\u0430\u0448\u04a1\u043e\u0440\u0442, Boarisch, \u017demait\u0117\u0161ka, \u0411\u0435\u043b\u0430\u0440\u0443\u0441\u043a\u0430\u044f, \u0411\u0435\u043b\u0430\u0440\u0443\u0441\u043a\u0430\u044f (\u0442\u0430\u0440\u0430\u0448\u043a\u0435\u0432\u0456\u0446\u0430), \u0411\u044a\u043b\u0433\u0430\u0440\u0441\u043a\u0438, Bamanankan, \u09ac\u09be\u0982\u09b2\u09be, Brezhoneg, Bosanski, Catal\u00e0, M\u00ecng-d\u0115\u0324ng-ng\u1e73\u0304, \u041d\u043e\u0445\u0447\u0438\u0439\u043d, Cebuano, \u13e3\u13b3\u13a9, \u010cesky, \u0421\u043b\u043e\u0432\u0463\u0301\u043d\u044c\u0441\u043a\u044a \/ \u2c14\u2c0e\u2c11\u2c02\u2c21\u2c10\u2c20\u2c14\u2c0d\u2c1f, \u0427\u04d1\u0432\u0430\u0448\u043b\u0430, Cymraeg, Dansk, Zazaki, \u078b\u07a8\u0788\u07ac\u0780\u07a8\u0784\u07a6\u0790\u07b0, \u0395\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ac, Emili\u00e0n e rumagn\u00f2l, English, Esperanto, Espa\u00f1ol, Eesti, Euskara, \u0641\u0627\u0631\u0633\u06cc, Suomi, V\u00f5ro, F\u00f8royskt, Fran\u00e7ais, Arpetan, Furlan, Frysk, Gaeilge, \u8d1b\u8a9e, G\u00e0idhlig, Galego, Ava\u00f1e\'\u1ebd, \u0a97\u0ac1\u0a9c\u0ab0\u0abe\u0aa4\u0ac0, Gaelg, \u05e2\u05d1\u05e8\u05d9\u05ea, \u0939\u093f\u0928\u094d\u0926\u0940, Fiji Hindi, Hrvatski, Krey\u00f2l ayisyen, Magyar, \u0540\u0561\u0575\u0565\u0580\u0565\u0576, Interlingua, Bahasa Indonesia, Ilokano, Ido, \u00cdslenska, Italiano, \u65e5\u672c\u8a9e, Lojban, Basa Jawa, \u10e5\u10d0\u10e0\u10d7\u10e3\u10da\u10d8, Kongo, Kalaallisut, \u0c95\u0ca8\u0ccd\u0ca8\u0ca1, \ud55c\uad6d\uc5b4, \u041a\u044a\u0430\u0440\u0430\u0447\u0430\u0439-\u041c\u0430\u043b\u043a\u044a\u0430\u0440, Ripoarisch, Kurd\u00ee, \u041a\u043e\u043c\u0438, Kernewek, \u041a\u044b\u0440\u0433\u044b\u0437\u0447\u0430, Latina, Ladino, L\u00ebtzebuergesch, Limburgs, Ling\u00e1la, \u0ea5\u0eb2\u0ea7, Lietuvi\u0173, Latvie\u0161u, Basa Banyumasan, Malagasy, \u041c\u0430\u043a\u0435\u0434\u043e\u043d\u0441\u043a\u0438, \u0d2e\u0d32\u0d2f\u0d3e\u0d33\u0d02, \u092e\u0930\u093e\u0920\u0940, Bahasa Melayu, \u0645\u0627\u0632\u0650\u0631\u0648\u0646\u06cc, Nnapulitano, Nedersaksisch, \u0928\u0947\u092a\u093e\u0932 \u092d\u093e\u0937\u093e, Nederlands, \u202aNorsk (nynorsk)\u202c, \u202aNorsk (bokm\u00e5l)\u202c, Nouormand, Din\u00e9 bizaad, Occitan, \u0418\u0440\u043e\u043d\u0430\u0443, Papiamentu, Deitsch, Norfuk \/ Pitkern, Polski, \u067e\u0646\u062c\u0627\u0628\u06cc, \u067e\u069a\u062a\u0648, Portugu\u00eas, Runa Simi, Rumantsch, Romani, Rom\u00e2n\u0103, \u0420\u0443\u0441\u0441\u043a\u0438\u0439, \u0421\u0430\u0445\u0430 \u0442\u044b\u043b\u0430, Sardu, Sicilianu, Scots, S\u00e1megiella, Simple English, Sloven\u010dina, Sloven\u0161\u010dina, \u0421\u0440\u043f\u0441\u043a\u0438 \/ Srpski, Seeltersk, Svenska, Kiswahili, \u0ba4\u0bae\u0bbf\u0bb4\u0bcd, \u0c24\u0c46\u0c32\u0c41\u0c17\u0c41, \u0422\u043e\u04b7\u0438\u043a\u04e3, \u0e44\u0e17\u0e22, T\u00fcrkmen\u00e7e, Tagalog, T\u00fcrk\u00e7e, \u0422\u0430\u0442\u0430\u0440\u0447\u0430\/Tatar\u00e7a, \u0423\u043a\u0440\u0430\u0457\u043d\u0441\u044c\u043a\u0430, \u0627\u0631\u062f\u0648, Ti\u1ebfng Vi\u1ec7t, Volap\u00fck, Walon, Winaray, \u5434\u8bed, isiXhosa, \u05d9\u05d9\u05b4\u05d3\u05d9\u05e9, Yor\u00f9b\u00e1, Ze\u00eauws, \u4e2d\u6587, B\u00e2n-l\u00e2m-g\u00fa, \u7cb5\u8a9e":"long key"}]}}', + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testStringMap_args::class, + 'argsPropertyName' => 'thing', + 'expectedValue' => [ + "a" => "123", + "a b" => "with spaces ", + "same" => "same", + "0" => "numeric key", + "longValue" => "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ú, 粵語", + "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ú, 粵語" => "long key" + ], + 'expectedResult' => 12, + ]; + yield 'set' => [ + 'buffer' => '{"1":{"set":["i32",3,1,5,6]}}', + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testSet_args::class, + 'argsPropertyName' => 'thing', + 'expectedValue' => [1 => true, 5 => true, 6 => true], + 'expectedResult' => 4, + ]; + yield 'list' => [ + 'buffer' => '{"1":{"lst":["i32",3,1,2,3]}}', + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testList_args::class, + 'argsPropertyName' => 'thing', + 'expectedValue' => [1, 2, 3], + 'expectedResult' => 4, + ]; + yield 'enum' => [ + 'buffer' => '{"1":{"i32":6}}', + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testEnum_args::class, + 'argsPropertyName' => 'thing', + 'expectedValue' => Numberz::SIX, + 'expectedResult' => 1, + ]; + yield 'typedef' => [ + 'buffer' => '{"1":{"i64":69}}', + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testTypedef_args::class, + 'argsPropertyName' => 'thing', + 'expectedValue' => 69, + 'expectedResult' => 1, + ]; + yield 'mapmap' => [ + 'buffer' => '{"0":{"map":["i32","map",2,{"4":["i32","i32",4,{"1":1,"2":2,"3":3,"4":4}],"-4":["i32","i32",4,{"-4":-4,"-3":-3,"-2":-2,"-1":-1}]}]}}', + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testMapMap_result::class, + 'argsPropertyName' => 'success', + 'expectedValue' => [ + 4 => [ + 1 => 1, + 2 => 2, + 3 => 3, + 4 => 4, + ], + -4 => [ + -4 => -4, + -3 => -3, + -2 => -2, + -1 => -1 + ] + ], + 'expectedResult' => 18, + ]; + + $xtruct1 = new Xtruct( + [ + 'string_thing' => 'Goodbye4', + 'byte_thing' => 4, + 'i32_thing' => 4, + 'i64_thing' => 4, + ] + ); + + $xtruct2 = new Xtruct( + [ + 'string_thing' => 'Hello2', + 'byte_thing' => 2, + 'i32_thing' => 2, + 'i64_thing' => 2, + ] + ); + + $userMap = [Numberz::FIVE => 5, Numberz::EIGHT => 8]; + + $insanity2 = new Insanity( + [ + 'userMap' => $userMap, + 'xtructs' => [$xtruct1, $xtruct2], + ] + ); + + $insanity3 = $insanity2; + + $insanity6 = + new Insanity( + [ + 'userMap' => null, + 'xtructs' => null, + ] + ); + yield 'insanity' => [ + 'buffer' => '{"0":{"map":["i64","map",2,{"1":["i32","rec",2,{"2":{"1":{"map":["i32","i64",2,{"5":5,"8":8}]},"2":{"lst":["rec",2,{"1":{"str":"Goodbye4"},"4":{"i8":4},"9":{"i32":4},"11":{"i64":4}},{"1":{"str":"Hello2"},"4":{"i8":2},"9":{"i32":2},"11":{"i64":2}}]}},"3":{"1":{"map":["i32","i64",2,{"5":5,"8":8}]},"2":{"lst":["rec",2,{"1":{"str":"Goodbye4"},"4":{"i8":4},"9":{"i32":4},"11":{"i64":4}},{"1":{"str":"Hello2"},"4":{"i8":2},"9":{"i32":2},"11":{"i64":2}}]}}}],"2":["i32","rec",1,{"6":{}}]}]}}', + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testInsanity_result::class, + 'argsPropertyName' => 'success', + 'expectedValue' => [ + "1" => [ + Numberz::TWO => $insanity2, + Numberz::THREE => $insanity3, + ], + "2" => [ + Numberz::SIX => $insanity6, + ], + ], + 'expectedResult' => 31, + ]; + } +} diff --git a/lib/php/test/Integration/Lib/Protocol/TSimpleJSONProtocolTest.php b/lib/php/test/Integration/Lib/Protocol/TSimpleJSONProtocolTest.php new file mode 100644 index 00000000000..e108ffcb7f5 --- /dev/null +++ b/lib/php/test/Integration/Lib/Protocol/TSimpleJSONProtocolTest.php @@ -0,0 +1,319 @@ +transport = new TMemoryBuffer(); + $this->protocol = new TSimpleJSONProtocol($this->transport); + $this->transport->open(); + } + + public function testMessageWrite() + { + $input = new TJSONProtocol(new TMemoryBuffer('[1,"testString",1,0,{"0":{"str":"successResponse"}}]')); + $service = new \Basic\ThriftTest\ThriftTestClient($input, $this->protocol); + $result = $service->testString('test'); + $this->assertSame('successResponse', $result); + $this->assertSame('["testString",1,0,{"thing":"test"}]', $this->protocol->getTransport()->getBuffer()); + } + + /** + * @dataProvider writeDataProvider + */ + public function testWrite( + $argsClassName, + $argsValues, + $expected + ) { + $args = new $argsClassName($argsValues); + $args->write($this->protocol); + + $actual = $this->transport->read(self::BUFFER_SIZE); + + $this->assertEquals($expected, $actual); + } + + public function writeDataProvider() + { + if (!is_dir(__DIR__ . '/../../../Resources/packages/php')) { + throw new \RuntimeException( + 'Before running Integration test suite, you must run the Thrift compiler against the ThriftTest.thrift file in the ./Resources directory.' + ); + } + + yield 'void' => [ + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testVoid_args::class, + 'argsValues' => [], + 'expected' => '{}', + ]; + yield 'bool true' => [ + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testBool_args::class, + 'argsValues' => [ + 'thing' => true, + ], + 'expected' => '{"thing":1}', + ]; + yield 'bool false' => [ + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testBool_args::class, + 'argsValues' => [ + 'thing' => false, + ], + 'expected' => '{"thing":0}', + ]; + yield 'string1' => [ + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testString_args::class, + 'argsValues' => [ + 'thing' => "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ú, 粵語", + ], + 'expected' => '{"thing":"Afrikaans, Alemannisch, Aragon\u00e9s, \u0627\u0644\u0639\u0631\u0628\u064a\u0629, \u0645\u0635\u0631\u0649, Asturianu, Aymar aru, Az\u0259rbaycan, \u0411\u0430\u0448\u04a1\u043e\u0440\u0442, Boarisch, \u017demait\u0117\u0161ka, \u0411\u0435\u043b\u0430\u0440\u0443\u0441\u043a\u0430\u044f, \u0411\u0435\u043b\u0430\u0440\u0443\u0441\u043a\u0430\u044f (\u0442\u0430\u0440\u0430\u0448\u043a\u0435\u0432\u0456\u0446\u0430), \u0411\u044a\u043b\u0433\u0430\u0440\u0441\u043a\u0438, Bamanankan, \u09ac\u09be\u0982\u09b2\u09be, Brezhoneg, Bosanski, Catal\u00e0, M\u00ecng-d\u0115\u0324ng-ng\u1e73\u0304, \u041d\u043e\u0445\u0447\u0438\u0439\u043d, Cebuano, \u13e3\u13b3\u13a9, \u010cesky, \u0421\u043b\u043e\u0432\u0463\u0301\u043d\u044c\u0441\u043a\u044a \/ \u2c14\u2c0e\u2c11\u2c02\u2c21\u2c10\u2c20\u2c14\u2c0d\u2c1f, \u0427\u04d1\u0432\u0430\u0448\u043b\u0430, Cymraeg, Dansk, Zazaki, \u078b\u07a8\u0788\u07ac\u0780\u07a8\u0784\u07a6\u0790\u07b0, \u0395\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ac, Emili\u00e0n e rumagn\u00f2l, English, Esperanto, Espa\u00f1ol, Eesti, Euskara, \u0641\u0627\u0631\u0633\u06cc, Suomi, V\u00f5ro, F\u00f8royskt, Fran\u00e7ais, Arpetan, Furlan, Frysk, Gaeilge, \u8d1b\u8a9e, G\u00e0idhlig, Galego, Ava\u00f1e\'\u1ebd, \u0a97\u0ac1\u0a9c\u0ab0\u0abe\u0aa4\u0ac0, Gaelg, \u05e2\u05d1\u05e8\u05d9\u05ea, \u0939\u093f\u0928\u094d\u0926\u0940, Fiji Hindi, Hrvatski, Krey\u00f2l ayisyen, Magyar, \u0540\u0561\u0575\u0565\u0580\u0565\u0576, Interlingua, Bahasa Indonesia, Ilokano, Ido, \u00cdslenska, Italiano, \u65e5\u672c\u8a9e, Lojban, Basa Jawa, \u10e5\u10d0\u10e0\u10d7\u10e3\u10da\u10d8, Kongo, Kalaallisut, \u0c95\u0ca8\u0ccd\u0ca8\u0ca1, \ud55c\uad6d\uc5b4, \u041a\u044a\u0430\u0440\u0430\u0447\u0430\u0439-\u041c\u0430\u043b\u043a\u044a\u0430\u0440, Ripoarisch, Kurd\u00ee, \u041a\u043e\u043c\u0438, Kernewek, \u041a\u044b\u0440\u0433\u044b\u0437\u0447\u0430, Latina, Ladino, L\u00ebtzebuergesch, Limburgs, Ling\u00e1la, \u0ea5\u0eb2\u0ea7, Lietuvi\u0173, Latvie\u0161u, Basa Banyumasan, Malagasy, \u041c\u0430\u043a\u0435\u0434\u043e\u043d\u0441\u043a\u0438, \u0d2e\u0d32\u0d2f\u0d3e\u0d33\u0d02, \u092e\u0930\u093e\u0920\u0940, Bahasa Melayu, \u0645\u0627\u0632\u0650\u0631\u0648\u0646\u06cc, Nnapulitano, Nedersaksisch, \u0928\u0947\u092a\u093e\u0932 \u092d\u093e\u0937\u093e, Nederlands, \u202aNorsk (nynorsk)\u202c, \u202aNorsk (bokm\u00e5l)\u202c, Nouormand, Din\u00e9 bizaad, Occitan, \u0418\u0440\u043e\u043d\u0430\u0443, Papiamentu, Deitsch, Norfuk \/ Pitkern, Polski, \u067e\u0646\u062c\u0627\u0628\u06cc, \u067e\u069a\u062a\u0648, Portugu\u00eas, Runa Simi, Rumantsch, Romani, Rom\u00e2n\u0103, \u0420\u0443\u0441\u0441\u043a\u0438\u0439, \u0421\u0430\u0445\u0430 \u0442\u044b\u043b\u0430, Sardu, Sicilianu, Scots, S\u00e1megiella, Simple English, Sloven\u010dina, Sloven\u0161\u010dina, \u0421\u0440\u043f\u0441\u043a\u0438 \/ Srpski, Seeltersk, Svenska, Kiswahili, \u0ba4\u0bae\u0bbf\u0bb4\u0bcd, \u0c24\u0c46\u0c32\u0c41\u0c17\u0c41, \u0422\u043e\u04b7\u0438\u043a\u04e3, \u0e44\u0e17\u0e22, T\u00fcrkmen\u00e7e, Tagalog, T\u00fcrk\u00e7e, \u0422\u0430\u0442\u0430\u0440\u0447\u0430\/Tatar\u00e7a, \u0423\u043a\u0440\u0430\u0457\u043d\u0441\u044c\u043a\u0430, \u0627\u0631\u062f\u0648, Ti\u1ebfng Vi\u1ec7t, Volap\u00fck, Walon, Winaray, \u5434\u8bed, isiXhosa, \u05d9\u05d9\u05b4\u05d3\u05d9\u05e9, Yor\u00f9b\u00e1, Ze\u00eauws, \u4e2d\u6587, B\u00e2n-l\u00e2m-g\u00fa, \u7cb5\u8a9e"}', + ]; + yield 'string2' => [ + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testString_args::class, + 'argsValues' => [ + 'thing' => "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: !@#\$%&()(&%$#{}{}<><><", + ], + 'expected' => '{"thing":"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: !@#$%&()(&%$#{}{}<><><"}', + ]; + + yield 'string3' => [ + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testString_args::class, + 'argsValues' => [ + 'thing' => "string that ends in double-backslash \\\\", + ], + 'expected' => '{"thing":"string that ends in double-backslash \\\\\\\\"}', + ]; + yield 'string4 testUnicodeStringWithNonBMP' => [ + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testString_args::class, + 'argsValues' => [ + 'thing' => "สวัสดี/𝒯", + ], + 'expected' => '{"thing":"\u0e2a\u0e27\u0e31\u0e2a\u0e14\u0e35\/\ud835\udcaf"}', + ]; + yield 'double' => [ + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testDouble_args::class, + 'argsValues' => [ + 'thing' => 3.1415926535898, + ], + 'expected' => '{"thing":3.1415926535898}', + ]; + #TODO Should be fixed in future + yield 'double Nan' => [ + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testDouble_args::class, + 'argsValues' => [ + 'thing' => NAN, + ], + 'expected' => '{"thing":}', + ]; + #TODO Should be fixed in future + yield 'double Infinity' => [ + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testDouble_args::class, + 'argsValues' => [ + 'thing' => INF, + ], + 'expected' => '{"thing":}', + ]; + yield 'byte' => [ + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testByte_args::class, + 'argsValues' => [ + 'thing' => 0x01, + ], + 'expected' => '{"thing":1}', + ]; + yield 'i32' => [ + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testI32_args::class, + 'argsValues' => [ + 'thing' => pow(2, 30), + ], + 'expected' => '{"thing":1073741824}', + ]; + if (PHP_INT_SIZE == 8) { + yield 'i64_64Architecture' => [ + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testI64_args::class, + 'argsValues' => [ + 'thing' => pow(2, 60), + ], + 'expected' => '{"thing":' . pow(2, 60) . '}', + ]; + yield 'struct_64Architecture' => [ + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testStruct_args::class, + 'argsValues' => [ + 'thing' => new Xtruct( + [ + 'string_thing' => 'worked', + 'byte_thing' => 0x01, + 'i32_thing' => pow(2, 30), + 'i64_thing' => pow(2, 60), + ] + ), + ], + 'expected' => '{"thing":{"string_thing":"worked","byte_thing":1,"i32_thing":1073741824,"i64_thing":' . pow(2, 60) . '}}', + ]; + yield 'nest_64Architecture' => [ + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testNest_args::class, + 'argsValues' => [ + 'thing' => new Xtruct2( + [ + 'byte_thing' => 0x01, + 'struct_thing' => new Xtruct( + [ + 'string_thing' => 'worked', + 'byte_thing' => 0x01, + 'i32_thing' => pow(2, 30), + 'i64_thing' => pow(2, 60), + ] + ), + 'i32_thing' => pow(2, 15), + ] + ), + ], + 'expected' => '{"thing":{"byte_thing":1,"struct_thing":{"string_thing":"worked","byte_thing":1,"i32_thing":1073741824,"i64_thing":' . pow(2, 60) . '},"i32_thing":32768}}', + ]; + } else { + yield 'i64_32Architecture' => [ + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testI64_args::class, + 'argsValues' => [ + 'thing' => "1152921504606847000", + ], + 'expected' => '{"thing":1152921504606847000}', + ]; + yield 'struct_32Architecture' => [ + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testStruct_args::class, + 'argsValues' => [ + 'thing' => new Xtruct( + [ + 'string_thing' => 'worked', + 'byte_thing' => 0x01, + 'i32_thing' => pow(2, 30), + 'i64_thing' => pow(2, 60), + ] + ), + ], + 'expected' => '{"thing":{"string_thing":"worked","byte_thing":1,"i32_thing":1073741824,"i64_thing":1152921504606847000}}', + ]; + yield 'nest_32Architecture' => [ + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testNest_args::class, + 'argsValues' => [ + 'thing' => new Xtruct2( + [ + 'byte_thing' => 0x01, + 'struct_thing' => new Xtruct( + [ + 'string_thing' => 'worked', + 'byte_thing' => 0x01, + 'i32_thing' => pow(2, 30), + 'i64_thing' => '1152921504606847000', + ] + ), + 'i32_thing' => pow(2, 15), + ] + ), + ], + 'expected' => '{"thing":{"byte_thing":1,"struct_thing":{"string_thing":"worked","byte_thing":1,"i32_thing":1073741824,"i64_thing":1152921504606847000},"i32_thing":32768}}', + ]; + } + yield 'map' => [ + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testMap_args::class, + 'argsValues' => [ + 'thing' => [ + 7 => 77, + 8 => 88, + 9 => 99, + ], + ], + 'expected' => '{"thing":{"7":77,"8":88,"9":99}}', + ]; + yield 'stringMap' => [ + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testStringMap_args::class, + 'argsValues' => [ + 'thing' => [ + "a" => "123", + "a b" => "with spaces ", + "same" => "same", + "0" => "numeric key", + "longValue" => "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ú, 粵語", + "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ú, 粵語" => "long key" + ], + ], + 'expected' => '{"thing":{"a":"123","a b":"with spaces ","same":"same","0":"numeric key","longValue":"Afrikaans, Alemannisch, Aragon\u00e9s, \u0627\u0644\u0639\u0631\u0628\u064a\u0629, \u0645\u0635\u0631\u0649, Asturianu, Aymar aru, Az\u0259rbaycan, \u0411\u0430\u0448\u04a1\u043e\u0440\u0442, Boarisch, \u017demait\u0117\u0161ka, \u0411\u0435\u043b\u0430\u0440\u0443\u0441\u043a\u0430\u044f, \u0411\u0435\u043b\u0430\u0440\u0443\u0441\u043a\u0430\u044f (\u0442\u0430\u0440\u0430\u0448\u043a\u0435\u0432\u0456\u0446\u0430), \u0411\u044a\u043b\u0433\u0430\u0440\u0441\u043a\u0438, Bamanankan, \u09ac\u09be\u0982\u09b2\u09be, Brezhoneg, Bosanski, Catal\u00e0, M\u00ecng-d\u0115\u0324ng-ng\u1e73\u0304, \u041d\u043e\u0445\u0447\u0438\u0439\u043d, Cebuano, \u13e3\u13b3\u13a9, \u010cesky, \u0421\u043b\u043e\u0432\u0463\u0301\u043d\u044c\u0441\u043a\u044a \/ \u2c14\u2c0e\u2c11\u2c02\u2c21\u2c10\u2c20\u2c14\u2c0d\u2c1f, \u0427\u04d1\u0432\u0430\u0448\u043b\u0430, Cymraeg, Dansk, Zazaki, \u078b\u07a8\u0788\u07ac\u0780\u07a8\u0784\u07a6\u0790\u07b0, \u0395\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ac, Emili\u00e0n e rumagn\u00f2l, English, Esperanto, Espa\u00f1ol, Eesti, Euskara, \u0641\u0627\u0631\u0633\u06cc, Suomi, V\u00f5ro, F\u00f8royskt, Fran\u00e7ais, Arpetan, Furlan, Frysk, Gaeilge, \u8d1b\u8a9e, G\u00e0idhlig, Galego, Ava\u00f1e\'\u1ebd, \u0a97\u0ac1\u0a9c\u0ab0\u0abe\u0aa4\u0ac0, Gaelg, \u05e2\u05d1\u05e8\u05d9\u05ea, \u0939\u093f\u0928\u094d\u0926\u0940, Fiji Hindi, Hrvatski, Krey\u00f2l ayisyen, Magyar, \u0540\u0561\u0575\u0565\u0580\u0565\u0576, Interlingua, Bahasa Indonesia, Ilokano, Ido, \u00cdslenska, Italiano, \u65e5\u672c\u8a9e, Lojban, Basa Jawa, \u10e5\u10d0\u10e0\u10d7\u10e3\u10da\u10d8, Kongo, Kalaallisut, \u0c95\u0ca8\u0ccd\u0ca8\u0ca1, \ud55c\uad6d\uc5b4, \u041a\u044a\u0430\u0440\u0430\u0447\u0430\u0439-\u041c\u0430\u043b\u043a\u044a\u0430\u0440, Ripoarisch, Kurd\u00ee, \u041a\u043e\u043c\u0438, Kernewek, \u041a\u044b\u0440\u0433\u044b\u0437\u0447\u0430, Latina, Ladino, L\u00ebtzebuergesch, Limburgs, Ling\u00e1la, \u0ea5\u0eb2\u0ea7, Lietuvi\u0173, Latvie\u0161u, Basa Banyumasan, Malagasy, \u041c\u0430\u043a\u0435\u0434\u043e\u043d\u0441\u043a\u0438, \u0d2e\u0d32\u0d2f\u0d3e\u0d33\u0d02, \u092e\u0930\u093e\u0920\u0940, Bahasa Melayu, \u0645\u0627\u0632\u0650\u0631\u0648\u0646\u06cc, Nnapulitano, Nedersaksisch, \u0928\u0947\u092a\u093e\u0932 \u092d\u093e\u0937\u093e, Nederlands, \u202aNorsk (nynorsk)\u202c, \u202aNorsk (bokm\u00e5l)\u202c, Nouormand, Din\u00e9 bizaad, Occitan, \u0418\u0440\u043e\u043d\u0430\u0443, Papiamentu, Deitsch, Norfuk \/ Pitkern, Polski, \u067e\u0646\u062c\u0627\u0628\u06cc, \u067e\u069a\u062a\u0648, Portugu\u00eas, Runa Simi, Rumantsch, Romani, Rom\u00e2n\u0103, \u0420\u0443\u0441\u0441\u043a\u0438\u0439, \u0421\u0430\u0445\u0430 \u0442\u044b\u043b\u0430, Sardu, Sicilianu, Scots, S\u00e1megiella, Simple English, Sloven\u010dina, Sloven\u0161\u010dina, \u0421\u0440\u043f\u0441\u043a\u0438 \/ Srpski, Seeltersk, Svenska, Kiswahili, \u0ba4\u0bae\u0bbf\u0bb4\u0bcd, \u0c24\u0c46\u0c32\u0c41\u0c17\u0c41, \u0422\u043e\u04b7\u0438\u043a\u04e3, \u0e44\u0e17\u0e22, T\u00fcrkmen\u00e7e, Tagalog, T\u00fcrk\u00e7e, \u0422\u0430\u0442\u0430\u0440\u0447\u0430\/Tatar\u00e7a, \u0423\u043a\u0440\u0430\u0457\u043d\u0441\u044c\u043a\u0430, \u0627\u0631\u062f\u0648, Ti\u1ebfng Vi\u1ec7t, Volap\u00fck, Walon, Winaray, \u5434\u8bed, isiXhosa, \u05d9\u05d9\u05b4\u05d3\u05d9\u05e9, Yor\u00f9b\u00e1, Ze\u00eauws, \u4e2d\u6587, B\u00e2n-l\u00e2m-g\u00fa, \u7cb5\u8a9e","Afrikaans, Alemannisch, Aragon\u00e9s, \u0627\u0644\u0639\u0631\u0628\u064a\u0629, \u0645\u0635\u0631\u0649, Asturianu, Aymar aru, Az\u0259rbaycan, \u0411\u0430\u0448\u04a1\u043e\u0440\u0442, Boarisch, \u017demait\u0117\u0161ka, \u0411\u0435\u043b\u0430\u0440\u0443\u0441\u043a\u0430\u044f, \u0411\u0435\u043b\u0430\u0440\u0443\u0441\u043a\u0430\u044f (\u0442\u0430\u0440\u0430\u0448\u043a\u0435\u0432\u0456\u0446\u0430), \u0411\u044a\u043b\u0433\u0430\u0440\u0441\u043a\u0438, Bamanankan, \u09ac\u09be\u0982\u09b2\u09be, Brezhoneg, Bosanski, Catal\u00e0, M\u00ecng-d\u0115\u0324ng-ng\u1e73\u0304, \u041d\u043e\u0445\u0447\u0438\u0439\u043d, Cebuano, \u13e3\u13b3\u13a9, \u010cesky, \u0421\u043b\u043e\u0432\u0463\u0301\u043d\u044c\u0441\u043a\u044a \/ \u2c14\u2c0e\u2c11\u2c02\u2c21\u2c10\u2c20\u2c14\u2c0d\u2c1f, \u0427\u04d1\u0432\u0430\u0448\u043b\u0430, Cymraeg, Dansk, Zazaki, \u078b\u07a8\u0788\u07ac\u0780\u07a8\u0784\u07a6\u0790\u07b0, \u0395\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ac, Emili\u00e0n e rumagn\u00f2l, English, Esperanto, Espa\u00f1ol, Eesti, Euskara, \u0641\u0627\u0631\u0633\u06cc, Suomi, V\u00f5ro, F\u00f8royskt, Fran\u00e7ais, Arpetan, Furlan, Frysk, Gaeilge, \u8d1b\u8a9e, G\u00e0idhlig, Galego, Ava\u00f1e\'\u1ebd, \u0a97\u0ac1\u0a9c\u0ab0\u0abe\u0aa4\u0ac0, Gaelg, \u05e2\u05d1\u05e8\u05d9\u05ea, \u0939\u093f\u0928\u094d\u0926\u0940, Fiji Hindi, Hrvatski, Krey\u00f2l ayisyen, Magyar, \u0540\u0561\u0575\u0565\u0580\u0565\u0576, Interlingua, Bahasa Indonesia, Ilokano, Ido, \u00cdslenska, Italiano, \u65e5\u672c\u8a9e, Lojban, Basa Jawa, \u10e5\u10d0\u10e0\u10d7\u10e3\u10da\u10d8, Kongo, Kalaallisut, \u0c95\u0ca8\u0ccd\u0ca8\u0ca1, \ud55c\uad6d\uc5b4, \u041a\u044a\u0430\u0440\u0430\u0447\u0430\u0439-\u041c\u0430\u043b\u043a\u044a\u0430\u0440, Ripoarisch, Kurd\u00ee, \u041a\u043e\u043c\u0438, Kernewek, \u041a\u044b\u0440\u0433\u044b\u0437\u0447\u0430, Latina, Ladino, L\u00ebtzebuergesch, Limburgs, Ling\u00e1la, \u0ea5\u0eb2\u0ea7, Lietuvi\u0173, Latvie\u0161u, Basa Banyumasan, Malagasy, \u041c\u0430\u043a\u0435\u0434\u043e\u043d\u0441\u043a\u0438, \u0d2e\u0d32\u0d2f\u0d3e\u0d33\u0d02, \u092e\u0930\u093e\u0920\u0940, Bahasa Melayu, \u0645\u0627\u0632\u0650\u0631\u0648\u0646\u06cc, Nnapulitano, Nedersaksisch, \u0928\u0947\u092a\u093e\u0932 \u092d\u093e\u0937\u093e, Nederlands, \u202aNorsk (nynorsk)\u202c, \u202aNorsk (bokm\u00e5l)\u202c, Nouormand, Din\u00e9 bizaad, Occitan, \u0418\u0440\u043e\u043d\u0430\u0443, Papiamentu, Deitsch, Norfuk \/ Pitkern, Polski, \u067e\u0646\u062c\u0627\u0628\u06cc, \u067e\u069a\u062a\u0648, Portugu\u00eas, Runa Simi, Rumantsch, Romani, Rom\u00e2n\u0103, \u0420\u0443\u0441\u0441\u043a\u0438\u0439, \u0421\u0430\u0445\u0430 \u0442\u044b\u043b\u0430, Sardu, Sicilianu, Scots, S\u00e1megiella, Simple English, Sloven\u010dina, Sloven\u0161\u010dina, \u0421\u0440\u043f\u0441\u043a\u0438 \/ Srpski, Seeltersk, Svenska, Kiswahili, \u0ba4\u0bae\u0bbf\u0bb4\u0bcd, \u0c24\u0c46\u0c32\u0c41\u0c17\u0c41, \u0422\u043e\u04b7\u0438\u043a\u04e3, \u0e44\u0e17\u0e22, T\u00fcrkmen\u00e7e, Tagalog, T\u00fcrk\u00e7e, \u0422\u0430\u0442\u0430\u0440\u0447\u0430\/Tatar\u00e7a, \u0423\u043a\u0440\u0430\u0457\u043d\u0441\u044c\u043a\u0430, \u0627\u0631\u062f\u0648, Ti\u1ebfng Vi\u1ec7t, Volap\u00fck, Walon, Winaray, \u5434\u8bed, isiXhosa, \u05d9\u05d9\u05b4\u05d3\u05d9\u05e9, Yor\u00f9b\u00e1, Ze\u00eauws, \u4e2d\u6587, B\u00e2n-l\u00e2m-g\u00fa, \u7cb5\u8a9e":"long key"}}', + ]; + yield 'set' => [ + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testSet_args::class, + 'argsValues' => [ + 'thing' => [1 => true, 5 => true, 6 => true], + ], + 'expected' => '{"thing":[1,5,6]}', + ]; + yield 'list' => [ + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testList_args::class, + 'argsValues' => [ + 'thing' => [1, 2, 3], + ], + 'expected' => '{"thing":[1,2,3]}', + ]; + yield 'enum' => [ + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testEnum_args::class, + 'argsValues' => [ + 'thing' => \Basic\ThriftTest\Numberz::SIX, + ], + 'expected' => '{"thing":6}', + ]; + yield 'typedef' => [ + 'argsClassName' => \Basic\ThriftTest\ThriftTest_testTypedef_args::class, + 'argsValues' => [ + 'thing' => 69, + ], + 'expected' => '{"thing":69}', + ]; + } +} diff --git a/lib/php/test/Protocol/BinarySerializerTest.php b/lib/php/test/Integration/Lib/Serializer/BinarySerializerTest.php similarity index 61% rename from lib/php/test/Protocol/BinarySerializerTest.php rename to lib/php/test/Integration/Lib/Serializer/BinarySerializerTest.php index 71b0bb5066a..44eef937c51 100644 --- a/lib/php/test/Protocol/BinarySerializerTest.php +++ b/lib/php/test/Integration/Lib/Serializer/BinarySerializerTest.php @@ -17,44 +17,28 @@ * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. - * - * @package thrift.test */ -namespace Test\Thrift\Protocol; +namespace Test\Thrift\Integration\Lib\Serializer; use PHPUnit\Framework\TestCase; use Thrift\Serializer\TBinarySerializer; -require __DIR__ . '/../../../../vendor/autoload.php'; - /*** - * This test suite depends on running the compiler against the - * standard ThriftTest.thrift file: - * - * lib/php/test$ ../../../compiler/cpp/thrift --gen php -r \ - * --out ./packages ../../../test/ThriftTest.thrift - * - * @runTestsInSeparateProcesses + * This test suite depends on running the compiler against the ./Resources/ThriftTest.thrift file: + * lib/php/test$ ../../../compiler/cpp/thrift --gen php:nsglobal="Basic" -r --out ./Resources/packages/php ./Resources/ThriftTest.thrift */ class BinarySerializerTest extends TestCase { - public function setUp() - { - /** @var \Composer\Autoload\ClassLoader $loader */ - $loader = require __DIR__ . '/../../../../vendor/autoload.php'; - $loader->addPsr4('', __DIR__ . '/../packages/php'); - } - /** * We try to serialize and deserialize a random object to make sure no exceptions are thrown. * @see THRIFT-1579 */ public function testBinarySerializer() { - $struct = new \ThriftTest\Xtruct(array('string_thing' => 'abc')); - $serialized = TBinarySerializer::serialize($struct, 'ThriftTest\\Xtruct'); - $deserialized = TBinarySerializer::deserialize($serialized, 'ThriftTest\\Xtruct'); + $struct = new \Basic\ThriftTest\Xtruct(array('string_thing' => 'abc')); + $serialized = TBinarySerializer::serialize($struct, '\\Basic\\ThriftTest\\Xtruct'); + $deserialized = TBinarySerializer::deserialize($serialized, '\\Basic\\ThriftTest\\Xtruct'); $this->assertEquals($struct, $deserialized); } } diff --git a/lib/php/test/JsonSerialize/JsonSerializeTest.php b/lib/php/test/Integration/Lib/Serializer/JsonSerializeTest.php similarity index 69% rename from lib/php/test/JsonSerialize/JsonSerializeTest.php rename to lib/php/test/Integration/Lib/Serializer/JsonSerializeTest.php index c6686525fac..d3fe3f78cc1 100644 --- a/lib/php/test/JsonSerialize/JsonSerializeTest.php +++ b/lib/php/test/Integration/Lib/Serializer/JsonSerializeTest.php @@ -1,4 +1,5 @@ markTestSkipped('Requires PHP 5.4 or newer!'); - } - /** @var \Composer\Autoload\ClassLoader $loader */ - $loader = require __DIR__ . '/../../../../vendor/autoload.php'; - $loader->addPsr4('', __DIR__ . '/../packages/phpjs'); - } - public function testEmptyStruct() { - $empty = new \ThriftTest\EmptyStruct(array('non_existing_key' => 'bar')); + $empty = new \Json\ThriftTest\EmptyStruct(array('non_existing_key' => 'bar')); $this->assertEquals(new stdClass(), json_decode(json_encode($empty))); } @@ -52,7 +43,7 @@ public function testStringsAndInts() 'string_thing' => 'foo', 'i64_thing' => 1234567890, ); - $xtruct = new \ThriftTest\Xtruct($input); + $xtruct = new \Json\ThriftTest\Xtruct($input); // Xtruct's 'i32_thing' and 'byte_thing' fields should not be present here! $expected = new stdClass(); @@ -63,9 +54,9 @@ public function testStringsAndInts() public function testNestedStructs() { - $xtruct2 = new \ThriftTest\Xtruct2(array( + $xtruct2 = new \Json\ThriftTest\Xtruct2(array( 'byte_thing' => 42, - 'struct_thing' => new \ThriftTest\Xtruct(array( + 'struct_thing' => new \Json\ThriftTest\Xtruct(array( 'i32_thing' => 123456, )), )); @@ -80,8 +71,8 @@ public function testNestedStructs() public function testInsanity() { $xinput = array('string_thing' => 'foo'); - $xtruct = new \ThriftTest\Xtruct($xinput); - $insanity = new \ThriftTest\Insanity(array( + $xtruct = new \Json\ThriftTest\Xtruct($xinput); + $insanity = new \Json\ThriftTest\Insanity(array( 'xtructs' => array($xtruct, $xtruct, $xtruct) )); $expected = new stdClass(); @@ -91,8 +82,8 @@ public function testInsanity() public function testNestedLists() { - $bonk = new \ThriftTest\Bonk(array('message' => 'foo')); - $nested = new \ThriftTest\NestedListsBonk(array('bonk' => array(array(array($bonk))))); + $bonk = new \Json\ThriftTest\Bonk(array('message' => 'foo')); + $nested = new \Json\ThriftTest\NestedListsBonk(array('bonk' => array(array(array($bonk))))); $expected = new stdClass(); $expected->bonk = array(array(array((object)array('message' => 'foo')))); $this->assertEquals($expected, json_decode(json_encode($nested))); @@ -100,17 +91,17 @@ public function testNestedLists() public function testMaps() { - $intmap = new \ThriftTest\ThriftTest_testMap_args(['thing' => [0 => 'zero']]); - $emptymap = new \ThriftTest\ThriftTest_testMap_args([]); + $intmap = new \Json\ThriftTest\ThriftTest_testMap_args(['thing' => [0 => 'zero']]); + $emptymap = new \Json\ThriftTest\ThriftTest_testMap_args([]); $this->assertEquals('{"thing":{"0":"zero"}}', json_encode($intmap)); $this->assertEquals('{}', json_encode($emptymap)); } public function testScalarTypes() { - $b = new \ThriftTest\Bools(['im_true' => '1', 'im_false' => '0']); + $b = new \Json\ThriftTest\Bools(['im_true' => '1', 'im_false' => '0']); $this->assertEquals('{"im_true":true,"im_false":false}', json_encode($b)); - $s = new \ThriftTest\StructA(['s' => 42]); + $s = new \Json\ThriftTest\StructA(['s' => 42]); $this->assertEquals('{"s":"42"}', json_encode($s)); } } diff --git a/lib/php/test/Validator/ValidatorTestOop.php b/lib/php/test/Integration/ValidatorOopTest.php similarity index 63% rename from lib/php/test/Validator/ValidatorTestOop.php rename to lib/php/test/Integration/ValidatorOopTest.php index 93bca4d0cbc..c3dce030a2c 100644 --- a/lib/php/test/Validator/ValidatorTestOop.php +++ b/lib/php/test/Integration/ValidatorOopTest.php @@ -1,4 +1,5 @@ addPsr4('', __DIR__ . '/../packages/phpvo'); + return 'ValidateOop'; } } diff --git a/lib/php/test/Validator/ValidatorTest.php b/lib/php/test/Integration/ValidatorTest.php similarity index 67% rename from lib/php/test/Validator/ValidatorTest.php rename to lib/php/test/Integration/ValidatorTest.php index fa6c7a9f7e0..0d6a697e4eb 100644 --- a/lib/php/test/Validator/ValidatorTest.php +++ b/lib/php/test/Integration/ValidatorTest.php @@ -1,4 +1,5 @@ addPsr4('', __DIR__ . '/../packages/phpv'); + return 'Validate'; } } diff --git a/lib/php/test/Makefile.am b/lib/php/test/Makefile.am index 30765c34460..b6a53256e2b 100644 --- a/lib/php/test/Makefile.am +++ b/lib/php/test/Makefile.am @@ -19,37 +19,31 @@ PHPUNIT=php $(top_srcdir)/vendor/bin/phpunit -stubs: ../../../test/v0.16/ThriftTest.thrift TestValidators.thrift - mkdir -p ./packages/php - $(THRIFT) --gen php -r --out ./packages/php ../../../test/v0.16/ThriftTest.thrift - mkdir -p ./packages/phpv - mkdir -p ./packages/phpvo - mkdir -p ./packages/phpjs - $(THRIFT) --gen php:validate -r --out ./packages/phpv TestValidators.thrift - $(THRIFT) --gen php:validate,oop -r --out ./packages/phpvo TestValidators.thrift - $(THRIFT) --gen php:json -r --out ./packages/phpjs TestValidators.thrift +stubs: Resources/ThriftTest.thrift + mkdir -p ./Resources/packages/php + mkdir -p ./Resources/packages/phpv + mkdir -p ./Resources/packages/phpvo + mkdir -p ./Resources/packages/phpjs + mkdir -p ./Resources/packages/phpcm + $(THRIFT) --gen php:nsglobal="Basic" -r --out ./Resources/packages/php Resources/ThriftTest.thrift + $(THRIFT) --gen php:validate,nsglobal="Validate" -r --out ./Resources/packages/phpv Resources/ThriftTest.thrift + $(THRIFT) --gen php:validate,oop,nsglobal="ValidateOop" -r --out ./Resources/packages/phpvo Resources/ThriftTest.thrift + $(THRIFT) --gen php:json,nsglobal="Json" -r --out ./Resources/packages/phpjs Resources/ThriftTest.thrift + $(THRIFT) --gen php:classmap,server,rest,nsglobal="Classmap" -r --out ./Resources/packages/phpcm Resources/ThriftTest.thrift deps: $(top_srcdir)/composer.json composer install --working-dir=$(top_srcdir) all-local: deps -check-json-serializer: deps stubs - $(PHPUNIT) --log-junit=TEST-log-json-serializer.xml JsonSerialize/ - -check-validator: deps stubs - $(PHPUNIT) --log-junit=TEST-log-validator.xml Validator/ - -check-protocol: deps stubs - $(PHPUNIT) --log-junit=TEST-log-protocol.xml Protocol/ - -check: deps stubs \ - check-protocol \ - check-validator \ - check-json-serializer +check: deps stubs + $(PHPUNIT) --log-junit=test-log-junit.xml -c phpunit.xml / distclean-local: +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + clean-local: - $(RM) -r ./packages - $(RM) TEST-*.xml + $(RM) -r ./Resources/packages + $(RM) test-log-junit.xml diff --git a/lib/php/test/Protocol/TJSONProtocolFixtures.php b/lib/php/test/Protocol/TJSONProtocolFixtures.php deleted file mode 100644 index dd9039fcac0..00000000000 --- a/lib/php/test/Protocol/TJSONProtocolFixtures.php +++ /dev/null @@ -1,74 +0,0 @@ -<><"}}'; - - self::$testArgsJSON['testString3'] = '{"1":{"str":"string that ends in double-backslash \\\\\\\\"}}'; - - self::$testArgsJSON['testUnicodeStringWithNonBMP'] = '{"1":{"str":"สวัสดี\/𝒯"}}'; - - self::$testArgsJSON['testDouble'] = '{"1":{"dbl":3.1415926535898}}'; - - self::$testArgsJSON['testByte'] = '{"1":{"i8":1}}'; - - self::$testArgsJSON['testI32'] = '{"1":{"i32":1073741824}}'; - - if (PHP_INT_SIZE == 8) { - self::$testArgsJSON['testI64'] = '{"1":{"i64":' . pow(2, 60) . '}}'; - self::$testArgsJSON['testStruct'] = '{"1":{"rec":{"1":{"str":"worked"},"4":{"i8":1},"9":{"i32":1073741824},"11":{"i64":' . pow(2, 60) . '}}}}'; - self::$testArgsJSON['testNest'] = '{"1":{"rec":{"1":{"i8":1},"2":{"rec":{"1":{"str":"worked"},"4":{"i8":1},"9":{"i32":1073741824},"11":{"i64":' . pow(2, 60) . '}}},"3":{"i32":32768}}}}'; - } else { - self::$testArgsJSON['testI64'] = '{"1":{"i64":1152921504606847000}}'; - self::$testArgsJSON['testStruct'] = '{"1":{"rec":{"1":{"str":"worked"},"4":{"i8":1},"9":{"i32":1073741824},"11":{"i64":1152921504606847000}}}}'; - self::$testArgsJSON['testNest'] = '{"1":{"rec":{"1":{"i8":1},"2":{"rec":{"1":{"str":"worked"},"4":{"i8":1},"9":{"i32":1073741824},"11":{"i64":1152921504606847000}}},"3":{"i32":32768}}}}'; - } - - self::$testArgsJSON['testMap'] = '{"1":{"map":["i32","i32",3,{"7":77,"8":88,"9":99}]}}'; - - self::$testArgsJSON['testStringMap'] = '{"1":{"map":["str","str",6,{"a":"123","a b":"with spaces ","same":"same","0":"numeric key","longValue":"Afrikaans, Alemannisch, Aragon\u00e9s, \u0627\u0644\u0639\u0631\u0628\u064a\u0629, \u0645\u0635\u0631\u0649, Asturianu, Aymar aru, Az\u0259rbaycan, \u0411\u0430\u0448\u04a1\u043e\u0440\u0442, Boarisch, \u017demait\u0117\u0161ka, \u0411\u0435\u043b\u0430\u0440\u0443\u0441\u043a\u0430\u044f, \u0411\u0435\u043b\u0430\u0440\u0443\u0441\u043a\u0430\u044f (\u0442\u0430\u0440\u0430\u0448\u043a\u0435\u0432\u0456\u0446\u0430), \u0411\u044a\u043b\u0433\u0430\u0440\u0441\u043a\u0438, Bamanankan, \u09ac\u09be\u0982\u09b2\u09be, Brezhoneg, Bosanski, Catal\u00e0, M\u00ecng-d\u0115\u0324ng-ng\u1e73\u0304, \u041d\u043e\u0445\u0447\u0438\u0439\u043d, Cebuano, \u13e3\u13b3\u13a9, \u010cesky, \u0421\u043b\u043e\u0432\u0463\u0301\u043d\u044c\u0441\u043a\u044a \/ \u2c14\u2c0e\u2c11\u2c02\u2c21\u2c10\u2c20\u2c14\u2c0d\u2c1f, \u0427\u04d1\u0432\u0430\u0448\u043b\u0430, Cymraeg, Dansk, Zazaki, \u078b\u07a8\u0788\u07ac\u0780\u07a8\u0784\u07a6\u0790\u07b0, \u0395\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ac, Emili\u00e0n e rumagn\u00f2l, English, Esperanto, Espa\u00f1ol, Eesti, Euskara, \u0641\u0627\u0631\u0633\u06cc, Suomi, V\u00f5ro, F\u00f8royskt, Fran\u00e7ais, Arpetan, Furlan, Frysk, Gaeilge, \u8d1b\u8a9e, G\u00e0idhlig, Galego, Ava\u00f1e\'\u1ebd, \u0a97\u0ac1\u0a9c\u0ab0\u0abe\u0aa4\u0ac0, Gaelg, \u05e2\u05d1\u05e8\u05d9\u05ea, \u0939\u093f\u0928\u094d\u0926\u0940, Fiji Hindi, Hrvatski, Krey\u00f2l ayisyen, Magyar, \u0540\u0561\u0575\u0565\u0580\u0565\u0576, Interlingua, Bahasa Indonesia, Ilokano, Ido, \u00cdslenska, Italiano, \u65e5\u672c\u8a9e, Lojban, Basa Jawa, \u10e5\u10d0\u10e0\u10d7\u10e3\u10da\u10d8, Kongo, Kalaallisut, \u0c95\u0ca8\u0ccd\u0ca8\u0ca1, \ud55c\uad6d\uc5b4, \u041a\u044a\u0430\u0440\u0430\u0447\u0430\u0439-\u041c\u0430\u043b\u043a\u044a\u0430\u0440, Ripoarisch, Kurd\u00ee, \u041a\u043e\u043c\u0438, Kernewek, \u041a\u044b\u0440\u0433\u044b\u0437\u0447\u0430, Latina, Ladino, L\u00ebtzebuergesch, Limburgs, Ling\u00e1la, \u0ea5\u0eb2\u0ea7, Lietuvi\u0173, Latvie\u0161u, Basa Banyumasan, Malagasy, \u041c\u0430\u043a\u0435\u0434\u043e\u043d\u0441\u043a\u0438, \u0d2e\u0d32\u0d2f\u0d3e\u0d33\u0d02, \u092e\u0930\u093e\u0920\u0940, Bahasa Melayu, \u0645\u0627\u0632\u0650\u0631\u0648\u0646\u06cc, Nnapulitano, Nedersaksisch, \u0928\u0947\u092a\u093e\u0932 \u092d\u093e\u0937\u093e, Nederlands, \u202aNorsk (nynorsk)\u202c, \u202aNorsk (bokm\u00e5l)\u202c, Nouormand, Din\u00e9 bizaad, Occitan, \u0418\u0440\u043e\u043d\u0430\u0443, Papiamentu, Deitsch, Norfuk \/ Pitkern, Polski, \u067e\u0646\u062c\u0627\u0628\u06cc, \u067e\u069a\u062a\u0648, Portugu\u00eas, Runa Simi, Rumantsch, Romani, Rom\u00e2n\u0103, \u0420\u0443\u0441\u0441\u043a\u0438\u0439, \u0421\u0430\u0445\u0430 \u0442\u044b\u043b\u0430, Sardu, Sicilianu, Scots, S\u00e1megiella, Simple English, Sloven\u010dina, Sloven\u0161\u010dina, \u0421\u0440\u043f\u0441\u043a\u0438 \/ Srpski, Seeltersk, Svenska, Kiswahili, \u0ba4\u0bae\u0bbf\u0bb4\u0bcd, \u0c24\u0c46\u0c32\u0c41\u0c17\u0c41, \u0422\u043e\u04b7\u0438\u043a\u04e3, \u0e44\u0e17\u0e22, T\u00fcrkmen\u00e7e, Tagalog, T\u00fcrk\u00e7e, \u0422\u0430\u0442\u0430\u0440\u0447\u0430\/Tatar\u00e7a, \u0423\u043a\u0440\u0430\u0457\u043d\u0441\u044c\u043a\u0430, \u0627\u0631\u062f\u0648, Ti\u1ebfng Vi\u1ec7t, Volap\u00fck, Walon, Winaray, \u5434\u8bed, isiXhosa, \u05d9\u05d9\u05b4\u05d3\u05d9\u05e9, Yor\u00f9b\u00e1, Ze\u00eauws, \u4e2d\u6587, B\u00e2n-l\u00e2m-g\u00fa, \u7cb5\u8a9e","Afrikaans, Alemannisch, Aragon\u00e9s, \u0627\u0644\u0639\u0631\u0628\u064a\u0629, \u0645\u0635\u0631\u0649, Asturianu, Aymar aru, Az\u0259rbaycan, \u0411\u0430\u0448\u04a1\u043e\u0440\u0442, Boarisch, \u017demait\u0117\u0161ka, \u0411\u0435\u043b\u0430\u0440\u0443\u0441\u043a\u0430\u044f, \u0411\u0435\u043b\u0430\u0440\u0443\u0441\u043a\u0430\u044f (\u0442\u0430\u0440\u0430\u0448\u043a\u0435\u0432\u0456\u0446\u0430), \u0411\u044a\u043b\u0433\u0430\u0440\u0441\u043a\u0438, Bamanankan, \u09ac\u09be\u0982\u09b2\u09be, Brezhoneg, Bosanski, Catal\u00e0, M\u00ecng-d\u0115\u0324ng-ng\u1e73\u0304, \u041d\u043e\u0445\u0447\u0438\u0439\u043d, Cebuano, \u13e3\u13b3\u13a9, \u010cesky, \u0421\u043b\u043e\u0432\u0463\u0301\u043d\u044c\u0441\u043a\u044a \/ \u2c14\u2c0e\u2c11\u2c02\u2c21\u2c10\u2c20\u2c14\u2c0d\u2c1f, \u0427\u04d1\u0432\u0430\u0448\u043b\u0430, Cymraeg, Dansk, Zazaki, \u078b\u07a8\u0788\u07ac\u0780\u07a8\u0784\u07a6\u0790\u07b0, \u0395\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ac, Emili\u00e0n e rumagn\u00f2l, English, Esperanto, Espa\u00f1ol, Eesti, Euskara, \u0641\u0627\u0631\u0633\u06cc, Suomi, V\u00f5ro, F\u00f8royskt, Fran\u00e7ais, Arpetan, Furlan, Frysk, Gaeilge, \u8d1b\u8a9e, G\u00e0idhlig, Galego, Ava\u00f1e\'\u1ebd, \u0a97\u0ac1\u0a9c\u0ab0\u0abe\u0aa4\u0ac0, Gaelg, \u05e2\u05d1\u05e8\u05d9\u05ea, \u0939\u093f\u0928\u094d\u0926\u0940, Fiji Hindi, Hrvatski, Krey\u00f2l ayisyen, Magyar, \u0540\u0561\u0575\u0565\u0580\u0565\u0576, Interlingua, Bahasa Indonesia, Ilokano, Ido, \u00cdslenska, Italiano, \u65e5\u672c\u8a9e, Lojban, Basa Jawa, \u10e5\u10d0\u10e0\u10d7\u10e3\u10da\u10d8, Kongo, Kalaallisut, \u0c95\u0ca8\u0ccd\u0ca8\u0ca1, \ud55c\uad6d\uc5b4, \u041a\u044a\u0430\u0440\u0430\u0447\u0430\u0439-\u041c\u0430\u043b\u043a\u044a\u0430\u0440, Ripoarisch, Kurd\u00ee, \u041a\u043e\u043c\u0438, Kernewek, \u041a\u044b\u0440\u0433\u044b\u0437\u0447\u0430, Latina, Ladino, L\u00ebtzebuergesch, Limburgs, Ling\u00e1la, \u0ea5\u0eb2\u0ea7, Lietuvi\u0173, Latvie\u0161u, Basa Banyumasan, Malagasy, \u041c\u0430\u043a\u0435\u0434\u043e\u043d\u0441\u043a\u0438, \u0d2e\u0d32\u0d2f\u0d3e\u0d33\u0d02, \u092e\u0930\u093e\u0920\u0940, Bahasa Melayu, \u0645\u0627\u0632\u0650\u0631\u0648\u0646\u06cc, Nnapulitano, Nedersaksisch, \u0928\u0947\u092a\u093e\u0932 \u092d\u093e\u0937\u093e, Nederlands, \u202aNorsk (nynorsk)\u202c, \u202aNorsk (bokm\u00e5l)\u202c, Nouormand, Din\u00e9 bizaad, Occitan, \u0418\u0440\u043e\u043d\u0430\u0443, Papiamentu, Deitsch, Norfuk \/ Pitkern, Polski, \u067e\u0646\u062c\u0627\u0628\u06cc, \u067e\u069a\u062a\u0648, Portugu\u00eas, Runa Simi, Rumantsch, Romani, Rom\u00e2n\u0103, \u0420\u0443\u0441\u0441\u043a\u0438\u0439, \u0421\u0430\u0445\u0430 \u0442\u044b\u043b\u0430, Sardu, Sicilianu, Scots, S\u00e1megiella, Simple English, Sloven\u010dina, Sloven\u0161\u010dina, \u0421\u0440\u043f\u0441\u043a\u0438 \/ Srpski, Seeltersk, Svenska, Kiswahili, \u0ba4\u0bae\u0bbf\u0bb4\u0bcd, \u0c24\u0c46\u0c32\u0c41\u0c17\u0c41, \u0422\u043e\u04b7\u0438\u043a\u04e3, \u0e44\u0e17\u0e22, T\u00fcrkmen\u00e7e, Tagalog, T\u00fcrk\u00e7e, \u0422\u0430\u0442\u0430\u0440\u0447\u0430\/Tatar\u00e7a, \u0423\u043a\u0440\u0430\u0457\u043d\u0441\u044c\u043a\u0430, \u0627\u0631\u062f\u0648, Ti\u1ebfng Vi\u1ec7t, Volap\u00fck, Walon, Winaray, \u5434\u8bed, isiXhosa, \u05d9\u05d9\u05b4\u05d3\u05d9\u05e9, Yor\u00f9b\u00e1, Ze\u00eauws, \u4e2d\u6587, B\u00e2n-l\u00e2m-g\u00fa, \u7cb5\u8a9e":"long key"}]}}'; - - self::$testArgsJSON['testSet'] = '{"1":{"set":["i32",3,1,5,6]}}'; - - self::$testArgsJSON['testList'] = '{"1":{"lst":["i32",3,1,2,3]}}'; - - self::$testArgsJSON['testEnum'] = '{"1":{"i32":1}}'; - - self::$testArgsJSON['testTypedef'] = '{"1":{"i64":69}}'; - - self::$testArgsJSON['testMapMap'] = '{"0":{"map":["i32","map",2,{"4":["i32","i32",4,{"1":1,"2":2,"3":3,"4":4}],"-4":["i32","i32",4,{"-4":-4,"-3":-3,"-2":-2,"-1":-1}]}]}}'; - - self::$testArgsJSON['testInsanity'] = '{"0":{"map":["i64","map",2,{"1":["i32","rec",2,{"2":{"1":{"map":["i32","i64",2,{"5":5,"8":8}]},"2":{"lst":["rec",2,{"1":{"str":"Goodbye4"},"4":{"i8":4},"9":{"i32":4},"11":{"i64":4}},{"1":{"str":"Hello2"},"4":{"i8":2},"9":{"i32":2},"11":{"i64":2}}]}},"3":{"1":{"map":["i32","i64",2,{"5":5,"8":8}]},"2":{"lst":["rec",2,{"1":{"str":"Goodbye4"},"4":{"i8":4},"9":{"i32":4},"11":{"i64":4}},{"1":{"str":"Hello2"},"4":{"i8":2},"9":{"i32":2},"11":{"i64":2}}]}}}],"2":["i32","rec",1,{"6":{}}]}]}}'; - } -} diff --git a/lib/php/test/Protocol/TJSONProtocolTest.php b/lib/php/test/Protocol/TJSONProtocolTest.php deleted file mode 100644 index bf0ecce4293..00000000000 --- a/lib/php/test/Protocol/TJSONProtocolTest.php +++ /dev/null @@ -1,518 +0,0 @@ -addPsr4('', __DIR__ . '/../packages/php'); - - Fixtures::populateTestArgs(); - TJSONProtocolFixtures::populateTestArgsJSON(); - } - - public function setUp() - { - $this->transport = new TMemoryBuffer(); - $this->protocol = new TJSONProtocol($this->transport); - $this->transport->open(); - } - - /** - * WRITE TESTS - */ - public function testVoidWrite() - { - $args = new \ThriftTest\ThriftTest_testVoid_args(); - $args->write($this->protocol); - - $actual = $this->transport->read(Fixtures::$bufsize); - $expected = TJSONProtocolFixtures::$testArgsJSON['testVoid']; - - $this->assertEquals($expected, $actual); - } - - public function testString1Write() - { - $args = new \ThriftTest\ThriftTest_testString_args(); - $args->thing = Fixtures::$testArgs['testString1']; - $args->write($this->protocol); - - $actual = $this->transport->read(Fixtures::$bufsize); - $expected = TJSONProtocolFixtures::$testArgsJSON['testString1']; - - $this->assertEquals($expected, $actual); - } - - public function testString2Write() - { - $args = new \ThriftTest\ThriftTest_testString_args(); - $args->thing = Fixtures::$testArgs['testString2']; - $args->write($this->protocol); - - $actual = $this->transport->read(Fixtures::$bufsize); - $expected = TJSONProtocolFixtures::$testArgsJSON['testString2']; - - $this->assertEquals($expected, $actual); - } - - public function testDoubleWrite() - { - $args = new \ThriftTest\ThriftTest_testDouble_args(); - $args->thing = Fixtures::$testArgs['testDouble']; - $args->write($this->protocol); - - $actual = $this->transport->read(Fixtures::$bufsize); - $expected = TJSONProtocolFixtures::$testArgsJSON['testDouble']; - - $this->assertEquals($expected, $actual); - } - - public function testByteWrite() - { - $args = new \ThriftTest\ThriftTest_testByte_args(); - $args->thing = Fixtures::$testArgs['testByte']; - $args->write($this->protocol); - - $actual = $this->transport->read(Fixtures::$bufsize); - $expected = TJSONProtocolFixtures::$testArgsJSON['testByte']; - - $this->assertEquals($expected, $actual); - } - - public function testI32Write() - { - $args = new \ThriftTest\ThriftTest_testI32_args(); - $args->thing = Fixtures::$testArgs['testI32']; - $args->write($this->protocol); - - $actual = $this->transport->read(Fixtures::$bufsize); - $expected = TJSONProtocolFixtures::$testArgsJSON['testI32']; - - $this->assertEquals($expected, $actual); - } - - public function testI64Write() - { - $args = new \ThriftTest\ThriftTest_testI64_args(); - $args->thing = Fixtures::$testArgs['testI64']; - $args->write($this->protocol); - - $actual = $this->transport->read(Fixtures::$bufsize); - $expected = TJSONProtocolFixtures::$testArgsJSON['testI64']; - - $this->assertEquals($expected, $actual); - } - - public function testStructWrite() - { - $args = new \ThriftTest\ThriftTest_testStruct_args(); - $args->thing = Fixtures::$testArgs['testStruct']; - - $args->write($this->protocol); - - $actual = $this->transport->read(Fixtures::$bufsize); - $expected = TJSONProtocolFixtures::$testArgsJSON['testStruct']; - - $this->assertEquals($expected, $actual); - } - - public function testNestWrite() - { - $args = new \ThriftTest\ThriftTest_testNest_args(); - $args->thing = Fixtures::$testArgs['testNest']; - - $args->write($this->protocol); - - $actual = $this->transport->read(Fixtures::$bufsize); - $expected = TJSONProtocolFixtures::$testArgsJSON['testNest']; - - $this->assertEquals($expected, $actual); - } - - public function testMapWrite() - { - $args = new \ThriftTest\ThriftTest_testMap_args(); - $args->thing = Fixtures::$testArgs['testMap']; - - $args->write($this->protocol); - - $actual = $this->transport->read(Fixtures::$bufsize); - $expected = TJSONProtocolFixtures::$testArgsJSON['testMap']; - - $this->assertEquals($expected, $actual); - } - - public function testStringMapWrite() - { - $args = new \ThriftTest\ThriftTest_testStringMap_args(); - $args->thing = Fixtures::$testArgs['testStringMap']; - - $args->write($this->protocol); - - $actual = $this->transport->read(Fixtures::$bufsize); - $expected = TJSONProtocolFixtures::$testArgsJSON['testStringMap']; - - /* - * The $actual returns unescaped string. - * It is required to to decode then encode it again - * to get the expected escaped unicode. - */ - $this->assertEquals($expected, json_encode(json_decode($actual))); - } - - public function testSetWrite() - { - $args = new \ThriftTest\ThriftTest_testSet_args(); - $args->thing = Fixtures::$testArgs['testSet']; - - $args->write($this->protocol); - - $actual = $this->transport->read(Fixtures::$bufsize); - $expected = TJSONProtocolFixtures::$testArgsJSON['testSet']; - - $this->assertEquals($expected, $actual); - } - - public function testListWrite() - { - $args = new \ThriftTest\ThriftTest_testList_args(); - $args->thing = Fixtures::$testArgs['testList']; - - $args->write($this->protocol); - - $actual = $this->transport->read(Fixtures::$bufsize); - $expected = TJSONProtocolFixtures::$testArgsJSON['testList']; - - $this->assertEquals($expected, $actual); - } - - public function testEnumWrite() - { - $args = new \ThriftTest\ThriftTest_testEnum_args(); - $args->thing = Fixtures::$testArgs['testEnum']; - - $args->write($this->protocol); - - $actual = $this->transport->read(Fixtures::$bufsize); - $expected = TJSONProtocolFixtures::$testArgsJSON['testEnum']; - - $this->assertEquals($expected, $actual); - } - - public function testTypedefWrite() - { - $args = new \ThriftTest\ThriftTest_testTypedef_args(); - $args->thing = Fixtures::$testArgs['testTypedef']; - - $args->write($this->protocol); - - $actual = $this->transport->read(Fixtures::$bufsize); - $expected = TJSONProtocolFixtures::$testArgsJSON['testTypedef']; - - $this->assertEquals($expected, $actual); - } - - /** - * READ TESTS - */ - public function testVoidRead() - { - $this->transport->write( - TJSONProtocolFixtures::$testArgsJSON['testVoid'] - ); - $args = new \ThriftTest\ThriftTest_testVoid_args(); - $args->read($this->protocol); - } - - public function testString1Read() - { - $this->transport->write( - TJSONProtocolFixtures::$testArgsJSON['testString1'] - ); - $args = new \ThriftTest\ThriftTest_testString_args(); - $args->read($this->protocol); - - $actual = $args->thing; - $expected = Fixtures::$testArgs['testString1']; - - $this->assertEquals($expected, $actual); - } - - public function testString2Read() - { - $this->transport->write( - TJSONProtocolFixtures::$testArgsJSON['testString2'] - ); - $args = new \ThriftTest\ThriftTest_testString_args(); - $args->read($this->protocol); - - $actual = $args->thing; - $expected = Fixtures::$testArgs['testString2']; - - $this->assertEquals($expected, $actual); - } - - public function testString3Write() - { - $args = new \ThriftTest\ThriftTest_testString_args(); - $args->thing = Fixtures::$testArgs['testString3']; - $args->write($this->protocol); - - $actual = $this->transport->read(Fixtures::$bufsize); - $expected = TJSONProtocolFixtures::$testArgsJSON['testString3']; - - $this->assertEquals($expected, $actual); - } - - public function testString4Write() - { - $args = new \ThriftTest\ThriftTest_testString_args(); - $args->thing = Fixtures::$testArgs['testUnicodeStringWithNonBMP']; - $args->write($this->protocol); - - $actual = $this->transport->read(Fixtures::$bufsize); - $expected = TJSONProtocolFixtures::$testArgsJSON['testUnicodeStringWithNonBMP']; - - $this->assertEquals($expected, $actual); - } - - public function testDoubleRead() - { - $this->transport->write( - TJSONProtocolFixtures::$testArgsJSON['testDouble'] - ); - $args = new \ThriftTest\ThriftTest_testDouble_args(); - $args->read($this->protocol); - - $actual = $args->thing; - $expected = Fixtures::$testArgs['testDouble']; - - $this->assertEquals($expected, $actual); - } - - public function testByteRead() - { - $this->transport->write( - TJSONProtocolFixtures::$testArgsJSON['testByte'] - ); - $args = new \ThriftTest\ThriftTest_testByte_args(); - $args->read($this->protocol); - - $actual = $args->thing; - $expected = Fixtures::$testArgs['testByte']; - - $this->assertEquals($expected, $actual); - } - - public function testI32Read() - { - $this->transport->write( - TJSONProtocolFixtures::$testArgsJSON['testI32'] - ); - $args = new \ThriftTest\ThriftTest_testI32_args(); - $args->read($this->protocol); - - $actual = $args->thing; - $expected = Fixtures::$testArgs['testI32']; - - $this->assertEquals($expected, $actual); - } - - public function testI64Read() - { - $this->transport->write( - TJSONProtocolFixtures::$testArgsJSON['testI64'] - ); - $args = new \ThriftTest\ThriftTest_testI64_args(); - $args->read($this->protocol); - - $actual = $args->thing; - $expected = Fixtures::$testArgs['testI64']; - - $this->assertEquals($expected, $actual); - } - - public function testStructRead() - { - $this->transport->write( - TJSONProtocolFixtures::$testArgsJSON['testStruct'] - ); - $args = new \ThriftTest\ThriftTest_testStruct_args(); - $args->read($this->protocol); - - $actual = $args->thing; - $expected = Fixtures::$testArgs['testStruct']; - - $this->assertEquals($expected, $actual); - } - - public function testNestRead() - { - $this->transport->write( - TJSONProtocolFixtures::$testArgsJSON['testNest'] - ); - $args = new \ThriftTest\ThriftTest_testNest_args(); - $args->read($this->protocol); - - $actual = $args->thing; - $expected = Fixtures::$testArgs['testNest']; - - $this->assertEquals($expected, $actual); - } - - public function testMapRead() - { - $this->transport->write( - TJSONProtocolFixtures::$testArgsJSON['testMap'] - ); - $args = new \ThriftTest\ThriftTest_testMap_args(); - $args->read($this->protocol); - - $actual = $args->thing; - $expected = Fixtures::$testArgs['testMap']; - - $this->assertEquals($expected, $actual); - } - - public function testStringMapRead() - { - $this->transport->write( - TJSONProtocolFixtures::$testArgsJSON['testStringMap'] - ); - $args = new \ThriftTest\ThriftTest_testStringMap_args(); - $args->read($this->protocol); - - $actual = $args->thing; - $expected = Fixtures::$testArgs['testStringMap']; - - $this->assertEquals($expected, $actual); - } - - public function testSetRead() - { - $this->transport->write( - TJSONProtocolFixtures::$testArgsJSON['testSet'] - ); - $args = new \ThriftTest\ThriftTest_testSet_args(); - $args->read($this->protocol); - - $actual = $args->thing; - $expected = Fixtures::$testArgs['testSet']; - - $this->assertEquals($expected, $actual); - } - - public function testListRead() - { - $this->transport->write( - TJSONProtocolFixtures::$testArgsJSON['testList'] - ); - $args = new \ThriftTest\ThriftTest_testList_args(); - $args->read($this->protocol); - - $actual = $args->thing; - $expected = Fixtures::$testArgs['testList']; - - $this->assertEquals($expected, $actual); - } - - public function testEnumRead() - { - $this->transport->write( - TJSONProtocolFixtures::$testArgsJSON['testEnum'] - ); - $args = new \ThriftTest\ThriftTest_testEnum_args(); - $args->read($this->protocol); - - $actual = $args->thing; - $expected = Fixtures::$testArgs['testEnum']; - - $this->assertEquals($expected, $actual); - } - - public function testTypedefRead() - { - $this->transport->write( - TJSONProtocolFixtures::$testArgsJSON['testTypedef'] - ); - $args = new \ThriftTest\ThriftTest_testTypedef_args(); - $args->read($this->protocol); - - $actual = $args->thing; - $expected = Fixtures::$testArgs['testTypedef']; - - $this->assertEquals($expected, $actual); - } - - public function testMapMapRead() - { - $this->transport->write( - TJSONProtocolFixtures::$testArgsJSON['testMapMap'] - ); - $result = new \ThriftTest\ThriftTest_testMapMap_result(); - $result->read($this->protocol); - - $actual = $result->success; - $expected = Fixtures::$testArgs['testMapMapExpectedResult']; - - $this->assertEquals($expected, $actual); - } - - public function testInsanityRead() - { - $this->transport->write( - TJSONProtocolFixtures::$testArgsJSON['testInsanity'] - ); - $result = new \ThriftTest\ThriftTest_testInsanity_result(); - $result->read($this->protocol); - - $actual = $result->success; - $expected = Fixtures::$testArgs['testInsanityExpectedResult']; - - $this->assertEquals($expected, $actual); - } -} diff --git a/lib/php/test/Protocol/TSimpleJSONProtocolFixtures.php b/lib/php/test/Protocol/TSimpleJSONProtocolFixtures.php deleted file mode 100644 index 547fd86623d..00000000000 --- a/lib/php/test/Protocol/TSimpleJSONProtocolFixtures.php +++ /dev/null @@ -1,67 +0,0 @@ -<><"}'; - - self::$testArgsJSON['testDouble'] = '{"thing":3.1415926535898}'; - - self::$testArgsJSON['testByte'] = '{"thing":1}'; - - self::$testArgsJSON['testI32'] = '{"thing":1073741824}'; - - if (PHP_INT_SIZE == 8) { - self::$testArgsJSON['testI64'] = '{"thing":' . pow(2, 60) . '}'; - self::$testArgsJSON['testStruct'] = '{"thing":{"string_thing":"worked","byte_thing":1,"i32_thing":1073741824,"i64_thing":' . pow(2, 60) . '}}'; - self::$testArgsJSON['testNest'] = '{"thing":{"byte_thing":1,"struct_thing":{"string_thing":"worked","byte_thing":1,"i32_thing":1073741824,"i64_thing":' . pow(2, 60) . '},"i32_thing":32768}}'; - } else { - self::$testArgsJSON['testI64'] = '{"thing":1152921504606847000}'; - - self::$testArgsJSON['testStruct'] = '{"thing":{"string_thing":"worked","byte_thing":1,"i32_thing":1073741824,"i64_thing":1152921504606847000}}'; - self::$testArgsJSON['testNest'] = '{"thing":{"byte_thing":1,"struct_thing":{"string_thing":"worked","byte_thing":1,"i32_thing":1073741824,"i64_thing":1152921504606847000},"i32_thing":32768}}'; - } - - self::$testArgsJSON['testMap'] = '{"thing":{"7":77,"8":88,"9":99}}'; - - self::$testArgsJSON['testStringMap'] = '{"thing":{"a":"123","a b":"with spaces ","same":"same","0":"numeric key","longValue":"Afrikaans, Alemannisch, Aragon\u00e9s, \u0627\u0644\u0639\u0631\u0628\u064a\u0629, \u0645\u0635\u0631\u0649, Asturianu, Aymar aru, Az\u0259rbaycan, \u0411\u0430\u0448\u04a1\u043e\u0440\u0442, Boarisch, \u017demait\u0117\u0161ka, \u0411\u0435\u043b\u0430\u0440\u0443\u0441\u043a\u0430\u044f, \u0411\u0435\u043b\u0430\u0440\u0443\u0441\u043a\u0430\u044f (\u0442\u0430\u0440\u0430\u0448\u043a\u0435\u0432\u0456\u0446\u0430), \u0411\u044a\u043b\u0433\u0430\u0440\u0441\u043a\u0438, Bamanankan, \u09ac\u09be\u0982\u09b2\u09be, Brezhoneg, Bosanski, Catal\u00e0, M\u00ecng-d\u0115\u0324ng-ng\u1e73\u0304, \u041d\u043e\u0445\u0447\u0438\u0439\u043d, Cebuano, \u13e3\u13b3\u13a9, \u010cesky, \u0421\u043b\u043e\u0432\u0463\u0301\u043d\u044c\u0441\u043a\u044a \/ \u2c14\u2c0e\u2c11\u2c02\u2c21\u2c10\u2c20\u2c14\u2c0d\u2c1f, \u0427\u04d1\u0432\u0430\u0448\u043b\u0430, Cymraeg, Dansk, Zazaki, \u078b\u07a8\u0788\u07ac\u0780\u07a8\u0784\u07a6\u0790\u07b0, \u0395\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ac, Emili\u00e0n e rumagn\u00f2l, English, Esperanto, Espa\u00f1ol, Eesti, Euskara, \u0641\u0627\u0631\u0633\u06cc, Suomi, V\u00f5ro, F\u00f8royskt, Fran\u00e7ais, Arpetan, Furlan, Frysk, Gaeilge, \u8d1b\u8a9e, G\u00e0idhlig, Galego, Ava\u00f1e\'\u1ebd, \u0a97\u0ac1\u0a9c\u0ab0\u0abe\u0aa4\u0ac0, Gaelg, \u05e2\u05d1\u05e8\u05d9\u05ea, \u0939\u093f\u0928\u094d\u0926\u0940, Fiji Hindi, Hrvatski, Krey\u00f2l ayisyen, Magyar, \u0540\u0561\u0575\u0565\u0580\u0565\u0576, Interlingua, Bahasa Indonesia, Ilokano, Ido, \u00cdslenska, Italiano, \u65e5\u672c\u8a9e, Lojban, Basa Jawa, \u10e5\u10d0\u10e0\u10d7\u10e3\u10da\u10d8, Kongo, Kalaallisut, \u0c95\u0ca8\u0ccd\u0ca8\u0ca1, \ud55c\uad6d\uc5b4, \u041a\u044a\u0430\u0440\u0430\u0447\u0430\u0439-\u041c\u0430\u043b\u043a\u044a\u0430\u0440, Ripoarisch, Kurd\u00ee, \u041a\u043e\u043c\u0438, Kernewek, \u041a\u044b\u0440\u0433\u044b\u0437\u0447\u0430, Latina, Ladino, L\u00ebtzebuergesch, Limburgs, Ling\u00e1la, \u0ea5\u0eb2\u0ea7, Lietuvi\u0173, Latvie\u0161u, Basa Banyumasan, Malagasy, \u041c\u0430\u043a\u0435\u0434\u043e\u043d\u0441\u043a\u0438, \u0d2e\u0d32\u0d2f\u0d3e\u0d33\u0d02, \u092e\u0930\u093e\u0920\u0940, Bahasa Melayu, \u0645\u0627\u0632\u0650\u0631\u0648\u0646\u06cc, Nnapulitano, Nedersaksisch, \u0928\u0947\u092a\u093e\u0932 \u092d\u093e\u0937\u093e, Nederlands, \u202aNorsk (nynorsk)\u202c, \u202aNorsk (bokm\u00e5l)\u202c, Nouormand, Din\u00e9 bizaad, Occitan, \u0418\u0440\u043e\u043d\u0430\u0443, Papiamentu, Deitsch, Norfuk \/ Pitkern, Polski, \u067e\u0646\u062c\u0627\u0628\u06cc, \u067e\u069a\u062a\u0648, Portugu\u00eas, Runa Simi, Rumantsch, Romani, Rom\u00e2n\u0103, \u0420\u0443\u0441\u0441\u043a\u0438\u0439, \u0421\u0430\u0445\u0430 \u0442\u044b\u043b\u0430, Sardu, Sicilianu, Scots, S\u00e1megiella, Simple English, Sloven\u010dina, Sloven\u0161\u010dina, \u0421\u0440\u043f\u0441\u043a\u0438 \/ Srpski, Seeltersk, Svenska, Kiswahili, \u0ba4\u0bae\u0bbf\u0bb4\u0bcd, \u0c24\u0c46\u0c32\u0c41\u0c17\u0c41, \u0422\u043e\u04b7\u0438\u043a\u04e3, \u0e44\u0e17\u0e22, T\u00fcrkmen\u00e7e, Tagalog, T\u00fcrk\u00e7e, \u0422\u0430\u0442\u0430\u0440\u0447\u0430\/Tatar\u00e7a, \u0423\u043a\u0440\u0430\u0457\u043d\u0441\u044c\u043a\u0430, \u0627\u0631\u062f\u0648, Ti\u1ebfng Vi\u1ec7t, Volap\u00fck, Walon, Winaray, \u5434\u8bed, isiXhosa, \u05d9\u05d9\u05b4\u05d3\u05d9\u05e9, Yor\u00f9b\u00e1, Ze\u00eauws, \u4e2d\u6587, B\u00e2n-l\u00e2m-g\u00fa, \u7cb5\u8a9e","Afrikaans, Alemannisch, Aragon\u00e9s, \u0627\u0644\u0639\u0631\u0628\u064a\u0629, \u0645\u0635\u0631\u0649, Asturianu, Aymar aru, Az\u0259rbaycan, \u0411\u0430\u0448\u04a1\u043e\u0440\u0442, Boarisch, \u017demait\u0117\u0161ka, \u0411\u0435\u043b\u0430\u0440\u0443\u0441\u043a\u0430\u044f, \u0411\u0435\u043b\u0430\u0440\u0443\u0441\u043a\u0430\u044f (\u0442\u0430\u0440\u0430\u0448\u043a\u0435\u0432\u0456\u0446\u0430), \u0411\u044a\u043b\u0433\u0430\u0440\u0441\u043a\u0438, Bamanankan, \u09ac\u09be\u0982\u09b2\u09be, Brezhoneg, Bosanski, Catal\u00e0, M\u00ecng-d\u0115\u0324ng-ng\u1e73\u0304, \u041d\u043e\u0445\u0447\u0438\u0439\u043d, Cebuano, \u13e3\u13b3\u13a9, \u010cesky, \u0421\u043b\u043e\u0432\u0463\u0301\u043d\u044c\u0441\u043a\u044a \/ \u2c14\u2c0e\u2c11\u2c02\u2c21\u2c10\u2c20\u2c14\u2c0d\u2c1f, \u0427\u04d1\u0432\u0430\u0448\u043b\u0430, Cymraeg, Dansk, Zazaki, \u078b\u07a8\u0788\u07ac\u0780\u07a8\u0784\u07a6\u0790\u07b0, \u0395\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ac, Emili\u00e0n e rumagn\u00f2l, English, Esperanto, Espa\u00f1ol, Eesti, Euskara, \u0641\u0627\u0631\u0633\u06cc, Suomi, V\u00f5ro, F\u00f8royskt, Fran\u00e7ais, Arpetan, Furlan, Frysk, Gaeilge, \u8d1b\u8a9e, G\u00e0idhlig, Galego, Ava\u00f1e\'\u1ebd, \u0a97\u0ac1\u0a9c\u0ab0\u0abe\u0aa4\u0ac0, Gaelg, \u05e2\u05d1\u05e8\u05d9\u05ea, \u0939\u093f\u0928\u094d\u0926\u0940, Fiji Hindi, Hrvatski, Krey\u00f2l ayisyen, Magyar, \u0540\u0561\u0575\u0565\u0580\u0565\u0576, Interlingua, Bahasa Indonesia, Ilokano, Ido, \u00cdslenska, Italiano, \u65e5\u672c\u8a9e, Lojban, Basa Jawa, \u10e5\u10d0\u10e0\u10d7\u10e3\u10da\u10d8, Kongo, Kalaallisut, \u0c95\u0ca8\u0ccd\u0ca8\u0ca1, \ud55c\uad6d\uc5b4, \u041a\u044a\u0430\u0440\u0430\u0447\u0430\u0439-\u041c\u0430\u043b\u043a\u044a\u0430\u0440, Ripoarisch, Kurd\u00ee, \u041a\u043e\u043c\u0438, Kernewek, \u041a\u044b\u0440\u0433\u044b\u0437\u0447\u0430, Latina, Ladino, L\u00ebtzebuergesch, Limburgs, Ling\u00e1la, \u0ea5\u0eb2\u0ea7, Lietuvi\u0173, Latvie\u0161u, Basa Banyumasan, Malagasy, \u041c\u0430\u043a\u0435\u0434\u043e\u043d\u0441\u043a\u0438, \u0d2e\u0d32\u0d2f\u0d3e\u0d33\u0d02, \u092e\u0930\u093e\u0920\u0940, Bahasa Melayu, \u0645\u0627\u0632\u0650\u0631\u0648\u0646\u06cc, Nnapulitano, Nedersaksisch, \u0928\u0947\u092a\u093e\u0932 \u092d\u093e\u0937\u093e, Nederlands, \u202aNorsk (nynorsk)\u202c, \u202aNorsk (bokm\u00e5l)\u202c, Nouormand, Din\u00e9 bizaad, Occitan, \u0418\u0440\u043e\u043d\u0430\u0443, Papiamentu, Deitsch, Norfuk \/ Pitkern, Polski, \u067e\u0646\u062c\u0627\u0628\u06cc, \u067e\u069a\u062a\u0648, Portugu\u00eas, Runa Simi, Rumantsch, Romani, Rom\u00e2n\u0103, \u0420\u0443\u0441\u0441\u043a\u0438\u0439, \u0421\u0430\u0445\u0430 \u0442\u044b\u043b\u0430, Sardu, Sicilianu, Scots, S\u00e1megiella, Simple English, Sloven\u010dina, Sloven\u0161\u010dina, \u0421\u0440\u043f\u0441\u043a\u0438 \/ Srpski, Seeltersk, Svenska, Kiswahili, \u0ba4\u0bae\u0bbf\u0bb4\u0bcd, \u0c24\u0c46\u0c32\u0c41\u0c17\u0c41, \u0422\u043e\u04b7\u0438\u043a\u04e3, \u0e44\u0e17\u0e22, T\u00fcrkmen\u00e7e, Tagalog, T\u00fcrk\u00e7e, \u0422\u0430\u0442\u0430\u0440\u0447\u0430\/Tatar\u00e7a, \u0423\u043a\u0440\u0430\u0457\u043d\u0441\u044c\u043a\u0430, \u0627\u0631\u062f\u0648, Ti\u1ebfng Vi\u1ec7t, Volap\u00fck, Walon, Winaray, \u5434\u8bed, isiXhosa, \u05d9\u05d9\u05b4\u05d3\u05d9\u05e9, Yor\u00f9b\u00e1, Ze\u00eauws, \u4e2d\u6587, B\u00e2n-l\u00e2m-g\u00fa, \u7cb5\u8a9e":"long key"}}'; - - self::$testArgsJSON['testSet'] = '{"thing":[1,5,6]}'; - - self::$testArgsJSON['testList'] = '{"thing":[1,2,3]}'; - - self::$testArgsJSON['testEnum'] = '{"thing":1}'; - - self::$testArgsJSON['testTypedef'] = '{"thing":69}'; - } -} diff --git a/lib/php/test/Protocol/TSimpleJSONProtocolTest.php b/lib/php/test/Protocol/TSimpleJSONProtocolTest.php deleted file mode 100644 index e4a13736ed7..00000000000 --- a/lib/php/test/Protocol/TSimpleJSONProtocolTest.php +++ /dev/null @@ -1,254 +0,0 @@ -addPsr4('', __DIR__ . '/../packages/php'); - - Fixtures::populateTestArgs(); - TSimpleJSONProtocolFixtures::populateTestArgsSimpleJSON(); - } - - public function setUp() - { - $this->transport = new TMemoryBuffer(); - $this->protocol = new TSimpleJSONProtocol($this->transport); - $this->transport->open(); - } - - /** - * WRITE TESTS - */ - public function testVoidWrite() - { - $args = new \ThriftTest\ThriftTest_testVoid_args(); - $args->write($this->protocol); - - $actual = $this->transport->read(Fixtures::$bufsize); - $expected = TSimpleJSONProtocolFixtures::$testArgsJSON['testVoid']; - - $this->assertEquals($expected, $actual); - } - - public function testString1Write() - { - $args = new \ThriftTest\ThriftTest_testString_args(); - $args->thing = Fixtures::$testArgs['testString1']; - $args->write($this->protocol); - - $actual = $this->transport->read(Fixtures::$bufsize); - $expected = TSimpleJSONProtocolFixtures::$testArgsJSON['testString1']; - - $this->assertEquals($expected, $actual); - } - - public function testString2Write() - { - $args = new \ThriftTest\ThriftTest_testString_args(); - $args->thing = Fixtures::$testArgs['testString2']; - $args->write($this->protocol); - - $actual = $this->transport->read(Fixtures::$bufsize); - $expected = TSimpleJSONProtocolFixtures::$testArgsJSON['testString2']; - - $this->assertEquals($expected, $actual); - } - - public function testDoubleWrite() - { - $args = new \ThriftTest\ThriftTest_testDouble_args(); - $args->thing = Fixtures::$testArgs['testDouble']; - $args->write($this->protocol); - - $actual = $this->transport->read(Fixtures::$bufsize); - $expected = TSimpleJSONProtocolFixtures::$testArgsJSON['testDouble']; - - $this->assertEquals($expected, $actual); - } - - public function testByteWrite() - { - $args = new \ThriftTest\ThriftTest_testByte_args(); - $args->thing = Fixtures::$testArgs['testByte']; - $args->write($this->protocol); - - $actual = $this->transport->read(Fixtures::$bufsize); - $expected = TSimpleJSONProtocolFixtures::$testArgsJSON['testByte']; - - $this->assertEquals($expected, $actual); - } - - public function testI32Write() - { - $args = new \ThriftTest\ThriftTest_testI32_args(); - $args->thing = Fixtures::$testArgs['testI32']; - $args->write($this->protocol); - - $actual = $this->transport->read(Fixtures::$bufsize); - $expected = TSimpleJSONProtocolFixtures::$testArgsJSON['testI32']; - - $this->assertEquals($expected, $actual); - } - - public function testI64Write() - { - $args = new \ThriftTest\ThriftTest_testI64_args(); - $args->thing = Fixtures::$testArgs['testI64']; - $args->write($this->protocol); - - $actual = $this->transport->read(Fixtures::$bufsize); - $expected = TSimpleJSONProtocolFixtures::$testArgsJSON['testI64']; - - $this->assertEquals($expected, $actual); - } - - public function testStructWrite() - { - $args = new \ThriftTest\ThriftTest_testStruct_args(); - $args->thing = Fixtures::$testArgs['testStruct']; - - $args->write($this->protocol); - - $actual = $this->transport->read(Fixtures::$bufsize); - $expected = TSimpleJSONProtocolFixtures::$testArgsJSON['testStruct']; - - $this->assertEquals($expected, $actual); - } - - public function testNestWrite() - { - $args = new \ThriftTest\ThriftTest_testNest_args(); - $args->thing = Fixtures::$testArgs['testNest']; - - $args->write($this->protocol); - - $actual = $this->transport->read(Fixtures::$bufsize); - $expected = TSimpleJSONProtocolFixtures::$testArgsJSON['testNest']; - - $this->assertEquals($expected, $actual); - } - - public function testMapWrite() - { - $args = new \ThriftTest\ThriftTest_testMap_args(); - $args->thing = Fixtures::$testArgs['testMap']; - - $args->write($this->protocol); - - $actual = $this->transport->read(Fixtures::$bufsize); - $expected = TSimpleJSONProtocolFixtures::$testArgsJSON['testMap']; - - $this->assertEquals($expected, $actual); - } - - public function testStringMapWrite() - { - $args = new \ThriftTest\ThriftTest_testStringMap_args(); - $args->thing = Fixtures::$testArgs['testStringMap']; - - $args->write($this->protocol); - - $actual = $this->transport->read(Fixtures::$bufsize); - $expected = TSimpleJSONProtocolFixtures::$testArgsJSON['testStringMap']; - - $this->assertEquals($expected, $actual); - } - - public function testSetWrite() - { - $args = new \ThriftTest\ThriftTest_testSet_args(); - $args->thing = Fixtures::$testArgs['testSet']; - - $args->write($this->protocol); - - $actual = $this->transport->read(Fixtures::$bufsize); - $expected = TSimpleJSONProtocolFixtures::$testArgsJSON['testSet']; - - $this->assertEquals($expected, $actual); - } - - public function testListWrite() - { - $args = new \ThriftTest\ThriftTest_testList_args(); - $args->thing = Fixtures::$testArgs['testList']; - - $args->write($this->protocol); - - $actual = $this->transport->read(Fixtures::$bufsize); - $expected = TSimpleJSONProtocolFixtures::$testArgsJSON['testList']; - - $this->assertEquals($expected, $actual); - } - - public function testEnumWrite() - { - $args = new \ThriftTest\ThriftTest_testEnum_args(); - $args->thing = Fixtures::$testArgs['testEnum']; - - $args->write($this->protocol); - - $actual = $this->transport->read(Fixtures::$bufsize); - $expected = TSimpleJSONProtocolFixtures::$testArgsJSON['testEnum']; - - $this->assertEquals($expected, $actual); - } - - public function testTypedefWrite() - { - $args = new \ThriftTest\ThriftTest_testTypedef_args(); - $args->thing = Fixtures::$testArgs['testTypedef']; - - $args->write($this->protocol); - - $actual = $this->transport->read(Fixtures::$bufsize); - $expected = TSimpleJSONProtocolFixtures::$testArgsJSON['testTypedef']; - - $this->assertEquals($expected, $actual); - } -} diff --git a/lib/php/test/TestValidators.thrift b/lib/php/test/Resources/ThriftTest.thrift similarity index 95% rename from lib/php/test/TestValidators.thrift rename to lib/php/test/Resources/ThriftTest.thrift index a9804704ccc..07ca6e49203 100644 --- a/lib/php/test/TestValidators.thrift +++ b/lib/php/test/Resources/ThriftTest.thrift @@ -19,7 +19,7 @@ namespace php TestValidators -include "../../../test/v0.16/ThriftTest.thrift" +include "../../../../test/v0.16/ThriftTest.thrift" union UnionOfStrings { 1: string aa; diff --git a/lib/php/test/Unit/Lib/ClassLoader/Fixtures/A/TestClass.php b/lib/php/test/Unit/Lib/ClassLoader/Fixtures/A/TestClass.php new file mode 100644 index 00000000000..3652b253ead --- /dev/null +++ b/lib/php/test/Unit/Lib/ClassLoader/Fixtures/A/TestClass.php @@ -0,0 +1,30 @@ +getFunctionMock('Thrift\ClassLoader', 'apcu_fetch') + ->expects($useApcu ? $this->once() : $this->never()) + ->with($apcuPrefix . $class) + ->willReturn(false); + + $this->getFunctionMock('Thrift\ClassLoader', 'apcu_store') + ->expects($useApcu ? $this->once() : $this->never()) + ->with($apcuPrefix . $class, $this->anything()) + ->willReturn(true); + + $loader = new ThriftClassLoader($useApcu, $apcuPrefix); + foreach ($namespaces as $namespace => $paths) { + $loader->registerNamespace($namespace, $paths); + } + $loader->register(); + $loader->loadClass($class); + if ($isClassExist) { + $this->assertTrue(class_exists($class, false), "->loadClass() loads '$class'"); + } else { + $this->assertFalse(class_exists($class, false), "->loadClass() loads '$class'"); + } + } + + public function registerNamespaceDataProvider() + { + yield 'default' => [ + 'namespaces' => [ + 'A' => __DIR__ . '/Fixtures', + ], + 'class' => 'A\TestClass', + ]; + yield 'missedClass' => [ + 'namespaces' => [ + 'A' => __DIR__ . '/Fixtures', + ], + 'class' => 'A\MissedClass', + 'isClassExist' => false, + ]; + yield 'pathAsArray' => [ + 'namespaces' => [ + 'B' => [__DIR__ . '/Fixtures'], + ], + 'class' => 'B\TestClass', + ]; + yield 'loadClassWithSlash' => [ + 'namespaces' => [ + 'C' => __DIR__ . '/Fixtures', + ], + 'class' => '\C\TestClass', + ]; + yield 'severalNamespaces' => [ + 'namespaces' => [ + 'D' => __DIR__ . '/Fixtures', + 'E' => __DIR__ . '/Fixtures', + ], + 'class' => '\E\TestClass', + ]; + yield 'useApcu' => [ + 'namespaces' => [ + 'D' => __DIR__ . '/Fixtures', + 'E' => __DIR__ . '/Fixtures', + ], + 'class' => '\E\TestClass', + 'isClassExist' => true, + 'useApcu' => true, + 'apcuPrefix' => 'APCU_PREFIX', + ]; + } +} diff --git a/lib/php/test/Unit/Lib/Exception/TExceptionTest.php b/lib/php/test/Unit/Lib/Exception/TExceptionTest.php new file mode 100644 index 00000000000..add8803b0ea --- /dev/null +++ b/lib/php/test/Unit/Lib/Exception/TExceptionTest.php @@ -0,0 +1,60 @@ +assertInstanceOf(TException::class, $exception); + $this->assertSame($message, $exception->getMessage()); + $this->assertSame($code, $exception->getCode()); + } + + public function testExceptionWithSpecAndVals() + { + $spec = [ + ['var' => 'string'], + ['var' => 'int'], + ['var' => 'bool'], + ]; + + $vals = [ + 'string' => 'Test value', + 'int' => 123456, + 'bool' => true, + ]; + $exception = new TException($spec, $vals); + + $this->assertEquals('Test value', $exception->string); + $this->assertEquals(123456, $exception->int); + $this->assertEquals(true, $exception->bool); + } +} diff --git a/lib/php/test/Unit/Lib/Factory/TBinaryProtocolFactoryTest.php b/lib/php/test/Unit/Lib/Factory/TBinaryProtocolFactoryTest.php new file mode 100644 index 00000000000..76ff187d69d --- /dev/null +++ b/lib/php/test/Unit/Lib/Factory/TBinaryProtocolFactoryTest.php @@ -0,0 +1,79 @@ +createMock(TTransport::class); + $factory = new TBinaryProtocolFactory($strictRead, $strictWrite); + $protocol = $factory->getProtocol($transport); + + $this->assertInstanceOf(TBinaryProtocol::class, $protocol); + + $ref = new \ReflectionClass($protocol); + $refStrictRead = $ref->getProperty('strictRead_'); + $refStrictRead->setAccessible(true); + $refStrictWrite = $ref->getProperty('strictWrite_'); + $refStrictWrite->setAccessible(true); + $refTrans = $ref->getProperty('trans_'); + $refTrans->setAccessible(true); + + $this->assertEquals($strictRead, $refStrictRead->getValue($protocol)); + $this->assertEquals($strictWrite, $refStrictWrite->getValue($protocol)); + $this->assertSame($transport, $refTrans->getValue($protocol)); + } + + public function getProtocolDataProvider() + { + yield 'allTrue' => [ + 'strictRead' => true, + 'strictWrite' => true, + ]; + yield 'allFalse' => [ + 'strictRead' => false, + 'strictWrite' => false, + ]; + yield 'strictReadTrue' => [ + 'strictRead' => true, + 'strictWrite' => false, + ]; + yield 'strictWriteTrue' => [ + 'strictRead' => false, + 'strictWrite' => true, + ]; + } +} diff --git a/lib/php/test/Unit/Lib/Factory/TCompactProtocolFactoryTest.php b/lib/php/test/Unit/Lib/Factory/TCompactProtocolFactoryTest.php new file mode 100644 index 00000000000..1483c6ae2c5 --- /dev/null +++ b/lib/php/test/Unit/Lib/Factory/TCompactProtocolFactoryTest.php @@ -0,0 +1,48 @@ +createMock(TTransport::class); + $factory = new TCompactProtocolFactory(); + $protocol = $factory->getProtocol($transport); + + $this->assertInstanceOf(TCompactProtocol::class, $protocol); + + $ref = new \ReflectionClass($protocol); + $refTrans = $ref->getProperty('trans_'); + $refTrans->setAccessible(true); + + $this->assertSame($transport, $refTrans->getValue($protocol)); + } +} diff --git a/lib/php/test/Unit/Lib/Factory/TFramedTransportFactoryTest.php b/lib/php/test/Unit/Lib/Factory/TFramedTransportFactoryTest.php new file mode 100644 index 00000000000..f8a860c9739 --- /dev/null +++ b/lib/php/test/Unit/Lib/Factory/TFramedTransportFactoryTest.php @@ -0,0 +1,54 @@ +createMock(TTransport::class); + $factory = new TFramedTransportFactory(); + $framedTransport = $factory->getTransport($transport); + + $this->assertInstanceOf(TFramedTransport::class, $framedTransport); + + $ref = new \ReflectionClass($framedTransport); + $refRead = $ref->getProperty('read_'); + $refRead->setAccessible(true); + $refWrite = $ref->getProperty('write_'); + $refWrite->setAccessible(true); + $refTrans = $ref->getProperty('transport_'); + $refTrans->setAccessible(true); + + $this->assertTrue($refRead->getValue($framedTransport)); + $this->assertTrue($refWrite->getValue($framedTransport)); + $this->assertSame($transport, $refTrans->getValue($framedTransport)); + } +} diff --git a/lib/php/test/Unit/Lib/Factory/TJSONProtocolFactoryTest.php b/lib/php/test/Unit/Lib/Factory/TJSONProtocolFactoryTest.php new file mode 100644 index 00000000000..9c7055dbfbe --- /dev/null +++ b/lib/php/test/Unit/Lib/Factory/TJSONProtocolFactoryTest.php @@ -0,0 +1,48 @@ +createMock(TTransport::class); + $factory = new TJSONProtocolFactory(); + $protocol = $factory->getProtocol($transport); + + $this->assertInstanceOf(TJSONProtocol::class, $protocol); + + $ref = new \ReflectionClass($protocol); + $refTrans = $ref->getProperty('trans_'); + $refTrans->setAccessible(true); + + $this->assertSame($transport, $refTrans->getValue($protocol)); + } +} diff --git a/lib/php/test/Unit/Lib/Factory/TStringFuncFactoryTest.php b/lib/php/test/Unit/Lib/Factory/TStringFuncFactoryTest.php new file mode 100644 index 00000000000..c6feb2c3916 --- /dev/null +++ b/lib/php/test/Unit/Lib/Factory/TStringFuncFactoryTest.php @@ -0,0 +1,74 @@ +getFunctionMock('Thrift\Factory', 'ini_get') + ->expects($this->once()) + ->with('mbstring.func_overload') + ->willReturn($mbstringFuncOverload); + + $factory = new TStringFuncFactory(); + /** + * it is a hack to nullable the instance of TStringFuncFactory, and get a new instance based on the new ini_get value + */ + $ref = new \ReflectionClass($factory); + $refInstance = $ref->getProperty('_instance'); + $refInstance->setAccessible(true); + $refInstance->setValue($factory, null); + + $stringFunc = $factory::create(); + + $this->assertInstanceOf(TStringFunc::class, $stringFunc); + $this->assertInstanceOf($expectedClass, $stringFunc); + } + + public function createDataProvider() + { + yield 'mbstring' => [ + 'mbstring.func_overload' => 2, + 'expected' => Mbstring::class + ]; + + yield 'string' => [ + 'mbstring.func_overload' => 0, + 'expected' => Core::class + ]; + } +} diff --git a/lib/php/test/Unit/Lib/Factory/TTransportFactoryTest.php b/lib/php/test/Unit/Lib/Factory/TTransportFactoryTest.php new file mode 100644 index 00000000000..9d3e6402ba6 --- /dev/null +++ b/lib/php/test/Unit/Lib/Factory/TTransportFactoryTest.php @@ -0,0 +1,41 @@ +createMock(TTransport::class); + $factory = new TTransportFactory(); + $result = $factory->getTransport($transport); + + $this->assertSame($transport, $result); + } +} diff --git a/lib/php/test/Unit/Lib/Protocol/TBinaryProtocolAcceleratedTest.php b/lib/php/test/Unit/Lib/Protocol/TBinaryProtocolAcceleratedTest.php new file mode 100644 index 00000000000..4a82a5af040 --- /dev/null +++ b/lib/php/test/Unit/Lib/Protocol/TBinaryProtocolAcceleratedTest.php @@ -0,0 +1,73 @@ +assertInstanceOf($expectedTransport, $protocol->getTransport()); + } + + public function constructDataProvider() + { + yield 'not buffered transport' => [ + 'transport' => new TMemoryBuffer(), + 'expectedTransport' => TMemoryBuffer::class, + ]; + yield 'buffered transport' => [ + 'transport' => new TSocket(), + 'expectedTransport' => TBufferedTransport::class, + ]; + } + + /** + * @dataProvider strictParamsDataProvider + */ + public function testStrictParams($strictRead, $strictWrite) + { + $protocol = new TBinaryProtocolAccelerated(new TMemoryBuffer(), $strictRead, $strictWrite); + $this->assertEquals($strictRead, $protocol->isStrictRead()); + $this->assertEquals($strictWrite, $protocol->isStrictWrite()); + } + + public function strictParamsDataProvider() + { + yield 'strict read and write' => [true, true]; + yield 'not strict read and write' => [false, false]; + yield 'strict read and not strict write' => [true, false]; + yield 'not strict read and strict write' => [false, true]; + } +} diff --git a/lib/php/test/Unit/Lib/Protocol/TBinaryProtocolTest.php b/lib/php/test/Unit/Lib/Protocol/TBinaryProtocolTest.php new file mode 100644 index 00000000000..2648b556315 --- /dev/null +++ b/lib/php/test/Unit/Lib/Protocol/TBinaryProtocolTest.php @@ -0,0 +1,1009 @@ +createMock(TTransport::class); + $protocol = new TBinaryProtocol($transport, false, $strictWrite); + + $transport->expects($this->exactly(count($writeCallsParams))) + ->method('write') + ->withConsecutive(...$writeCallsParams) + ->willReturnOnConsecutiveCalls(...$writeCallsResults); + + $result = $protocol->writeMessageBegin($name, $type, $seqid); + $this->assertEquals($expectedResult, $result); + } + + public function writeMessageBeginDataProvider() + { + $type = TType::STRING; + $seqid = 555; + + yield 'strictWrite=true' => [ + 'strictWrite' => true, + 'name' => 'testName', + 'type' => $type, + 'seqid' => $seqid, + 'writeCallsParams' => [ + [pack('N', self::VERSION_1 | $type), 4], #writeI32 + [pack('N', strlen('testName')), 4], #writeStringLen + ['testName', 8], #writeString + [pack('N', $seqid), 4], #writeI32 + ], + 'writeCallsResults' => [ + 4, + 4, + 8, + 4, + ], + 'expectedResult' => 20, + ]; + + yield 'strictWrite=false' => [ + 'strictWrite' => false, + 'name' => 'testName', + 'type' => $type, + 'seqid' => $seqid, + 'writeCallsParams' => [ + [pack('N', strlen('testName')), 4], #writeStringLen + ['testName', 8], #writeString + [pack('c', $type), 1], #writeByte + [pack('N', $seqid), 4], #writeI32 + ], + 'writeCallsResults' => [ + 4, + 8, + 1, + 4, + ], + 'expectedResult' => 17, + ]; + } + + public function testWriteMessageEnd() + { + $transport = $this->createMock(TTransport::class); + $protocol = new TBinaryProtocol($transport, false, false); + + $this->assertEquals(0, $protocol->writeMessageEnd()); + } + + public function testWriteStructBegin() + { + $transport = $this->createMock(TTransport::class); + $protocol = new TBinaryProtocol($transport, false, false); + + $this->assertEquals(0, $protocol->writeStructBegin('testName')); + } + + public function testWriteStructEnd() + { + $transport = $this->createMock(TTransport::class); + $protocol = new TBinaryProtocol($transport, false, false); + + $this->assertEquals(0, $protocol->writeStructEnd()); + } + + public function testWriteFieldBegin() + { + $fieldName = 'testName'; + $fieldType = TType::STRING; + $fieldId = 555; + + $transport = $this->createMock(TTransport::class); + $protocol = new TBinaryProtocol($transport, false, false); + + $transport + ->expects($this->exactly(2)) + ->method('write') + ->withConsecutive( + ...[ + [pack('c', $fieldType), 1], #writeByte + [pack('n', $fieldId), 2], #writeI16 + ] + )->willReturnOnConsecutiveCalls([1, 2]); + + $this->assertEquals(3, $protocol->writeFieldBegin($fieldName, $fieldType, $fieldId)); + } + + public function testWriteFieldEnd() + { + $transport = $this->createMock(TTransport::class); + $protocol = new TBinaryProtocol($transport, false, false); + + $this->assertEquals(0, $protocol->writeFieldEnd()); + } + + public function testWriteFieldStop() + { + $transport = $this->createMock(TTransport::class); + $protocol = new TBinaryProtocol($transport, false, false); + + $transport + ->expects($this->once()) + ->method('write') + ->with(pack('c', TType::STOP), 1) #writeByte + ->willReturn(1); + + $this->assertEquals(1, $protocol->writeFieldStop()); + } + + public function testWriteMapBegin() + { + $keyType = TType::I32; + $valType = TType::STRING; + $size = 99; + + $transport = $this->createMock(TTransport::class); + $protocol = new TBinaryProtocol($transport, false, false); + + $transport + ->expects($this->exactly(3)) + ->method('write') + ->withConsecutive( + ...[ + [pack('c', $keyType), 1], #writeByte + [pack('c', $valType), 1], #writeByte + [pack('N', $size), 4], #writeI32 + ] + )->willReturnOnConsecutiveCalls([1, 1, 4]); + + $this->assertEquals(6, $protocol->writeMapBegin($keyType, $valType, $size)); + } + + public function testWriteMapEnd() + { + $transport = $this->createMock(TTransport::class); + $protocol = new TBinaryProtocol($transport, false, false); + + $this->assertEquals(0, $protocol->writeMapEnd()); + } + + public function testWriteListBegin() + { + $elemType = TType::I32; + $size = 99; + + $transport = $this->createMock(TTransport::class); + $protocol = new TBinaryProtocol($transport, false, false); + + $transport + ->expects($this->exactly(2)) + ->method('write') + ->withConsecutive( + ...[ + [pack('c', $elemType), 1], #writeByte + [pack('N', $size), 4], #writeI32 + ] + )->willReturnOnConsecutiveCalls([1, 4]); + + $this->assertEquals(5, $protocol->writeListBegin($elemType, $size)); + } + + public function testWriteListEnd() + { + $transport = $this->createMock(TTransport::class); + $protocol = new TBinaryProtocol($transport, false, false); + + $this->assertEquals(0, $protocol->writeListEnd()); + } + + public function testWriteSetBegin() + { + $elemType = TType::I32; + $size = 99; + + $transport = $this->createMock(TTransport::class); + $protocol = new TBinaryProtocol($transport, false, false); + + $transport + ->expects($this->exactly(2)) + ->method('write') + ->withConsecutive( + ...[ + [pack('c', $elemType), 1], #writeByte + [pack('N', $size), 4], #writeI32 + ] + )->willReturnOnConsecutiveCalls([1, 4]); + + $this->assertEquals(5, $protocol->writeSetBegin($elemType, $size)); + } + + public function testWriteSetEnd() + { + $transport = $this->createMock(TTransport::class); + $protocol = new TBinaryProtocol($transport, false, false); + + $this->assertEquals(0, $protocol->writeSetEnd()); + } + + public function testWriteBool() + { + $value = true; + $transport = $this->createMock(TTransport::class); + $protocol = new TBinaryProtocol($transport, false, false); + + $transport + ->expects($this->once()) + ->method('write') + ->with(pack('c', (int)$value), 1) #writeByte + ->willReturn(1); + + $this->assertEquals(1, $protocol->writeBool($value)); + } + + public function testWriteByte() + { + $value = 1; + $transport = $this->createMock(TTransport::class); + $protocol = new TBinaryProtocol($transport, false, false); + + $transport + ->expects($this->once()) + ->method('write') + ->with(pack('c', $value), 1) #writeByte + ->willReturn(1); + + $this->assertEquals(1, $protocol->writeByte($value)); + } + + public function testWriteI16() + { + $value = 1; + $transport = $this->createMock(TTransport::class); + $protocol = new TBinaryProtocol($transport, false, false); + + $transport + ->expects($this->once()) + ->method('write') + ->with(pack('n', $value), 2) #writeI16 + ->willReturn(2); + + $this->assertEquals(2, $protocol->writeI16($value)); + } + + public function testWriteI32() + { + $value = 1; + $transport = $this->createMock(TTransport::class); + $protocol = new TBinaryProtocol($transport, false, false); + + $transport + ->expects($this->once()) + ->method('write') + ->with(pack('N', $value), 4) #writeI32 + ->willReturn(4); + + $this->assertEquals(4, $protocol->writeI32($value)); + } + + public function testWriteI64For32BitArchitecture() + { + if (PHP_INT_SIZE !== 4) { + $this->markTestSkipped('Test is only for 32 bit architecture'); + } + $value = 1; + $transport = $this->createMock(TTransport::class); + $protocol = new TBinaryProtocol($transport, false, false); + + $neg = $value < 0; + + if ($neg) { + $value *= -1; + } + + $hi = (int)($value / 4294967296); + $lo = (int)$value; + + if ($neg) { + $hi = ~$hi; + $lo = ~$lo; + if (($lo & (int)0xffffffff) == (int)0xffffffff) { + $lo = 0; + $hi++; + } else { + $lo++; + } + } + + $transport + ->expects($this->once()) + ->method('write') + ->with(pack('N2', $hi, $lo), 8) #writeI64 + ->willReturn(4); + + $this->assertEquals(8, $protocol->writeI64($value)); + } + + public function testWriteI64For64BitArchitecture() + { + if (PHP_INT_SIZE == 4) { + $this->markTestSkipped('Test is only for 64 bit architecture'); + } + $value = 1; + $transport = $this->createMock(TTransport::class); + $protocol = new TBinaryProtocol($transport, false, false); + + $hi = $value >> 32; + $lo = $value & 0xFFFFFFFF; + + $transport + ->expects($this->once()) + ->method('write') + ->with(pack('N2', $hi, $lo), 8) #writeI64 + ->willReturn(8); + + $this->assertEquals(8, $protocol->writeI64($value)); + } + + public function testWriteDouble() + { + $value = 1; + $transport = $this->createMock(TTransport::class); + $protocol = new TBinaryProtocol($transport, false, false); + + $transport + ->expects($this->once()) + ->method('write') + ->with(strrev(pack('d', $value)), 8) #writeDouble + ->willReturn(8); + + $this->assertEquals(8, $protocol->writeDouble($value)); + } + + public function testWriteString() + { + $value = 'string'; + $transport = $this->createMock(TTransport::class); + $protocol = new TBinaryProtocol($transport, false, false); + + $transport + ->expects($this->exactly(2)) + ->method('write') + ->withConsecutive( + ...[ + [pack('N', strlen($value))], #writeI32, + [$value, strlen($value)], #write, + ] + )->willReturnOnConsecutiveCalls([4, 6]); + + $this->assertEquals(10, $protocol->writeString($value)); + } + + /** + * @dataProvider readMessageBeginDataProvider + */ + public function testReadMessageBegin( + $strictRead, + $readCallsParams, + $readCallsResults, + $expectedReadLengthResult, + $expectedName, + $expectedType, + $expectedSeqid, + $expectedException = null, + $expectedExceptionMessage = null, + $expectedExceptionCode = null + ) { + if ($expectedException) { + $this->expectException($expectedException); + $this->expectExceptionMessage($expectedExceptionMessage); + $this->expectExceptionCode($expectedExceptionCode); + } + + $transport = $this->createMock(TTransport::class); + $protocol = new TBinaryProtocol($transport, $strictRead, true); + + $transport->expects($this->exactly(count($readCallsParams))) + ->method('readAll') + ->withConsecutive(...$readCallsParams) + ->willReturnOnConsecutiveCalls(...$readCallsResults); + + $result = $protocol->readMessageBegin($name, $type, $seqid); + $this->assertEquals($expectedReadLengthResult, $result); + $this->assertEquals($expectedName, $name); + $this->assertEquals($expectedType, $type); + $this->assertEquals($expectedSeqid, $seqid); + } + + public function readMessageBeginDataProvider() + { + yield 'strictRead=true' => [ + 'strictRead' => true, + 'readCallsParams' => [ + [4], #readI32 + [4], #readStringLen + [8], #readString + [4], #readI32 + ], + 'readCallsResults' => [ + pack('N', 0x80010000 | TType::STRING), #version + pack('N', strlen('testName')), + 'testName', + pack('N', 555), + ], + 'expectedReadLengthResult' => 20, + 'expectedName' => 'testName', + 'expectedType' => TType::STRING, + 'expectedSeqid' => 555, + ]; + + yield 'incorrect version' => [ + 'strictRead' => true, + 'readCallsParams' => [ + [4], #readI32 + ], + 'readCallsResults' => [ + pack('N', 0x80000000 | TType::STRING), #version + ], + 'expectedReadLengthResult' => 4, + 'expectedName' => '', + 'expectedType' => 0, + 'expectedSeqid' => 0, + 'expectedException' => TProtocolException::class, + 'expectedExceptionMessage' => 'Bad version identifier: -2147483637', + 'expectedExceptionCode' => TProtocolException::BAD_VERSION, + ]; + + yield 'strictRead=false' => [ + 'strictRead' => false, + 'readCallsParams' => [ + [4], #readStringLen + [8], #readString + [1], #readByte + [4], #readI32 + ], + 'readCallsResults' => [ + pack('N', strlen('testName')), + 'testName', + pack('c', TType::STRING), + pack('N', 555), + ], + 'expectedReadLengthResult' => 17, + 'expectedName' => 'testName', + 'expectedType' => TType::STRING, + 'expectedSeqid' => 555, + ]; + + yield 'strictRead=true without version' => [ + 'strictRead' => true, + 'readCallsParams' => [ + [4], #readStringLen + ], + 'readCallsResults' => [ + pack('N', strlen('testName')), + ], + 'expectedReadLengthResult' => 17, + 'expectedName' => 'testName', + 'expectedType' => TType::STRING, + 'expectedSeqid' => 555, + 'expectedException' => TProtocolException::class, + 'expectedExceptionMessage' => 'No version identifier, old protocol client?', + 'expectedExceptionCode' => TProtocolException::BAD_VERSION, + ]; + } + + public function testReadMessageEnd() + { + $transport = $this->createMock(TTransport::class); + $protocol = new TBinaryProtocol($transport, false, false); + + $this->assertEquals(0, $protocol->readMessageEnd()); + } + + public function testReadStructBegin() + { + $transport = $this->createMock(TTransport::class); + $protocol = new TBinaryProtocol($transport, false, false); + + $this->assertEquals(0, $protocol->readStructBegin($name)); + $this->assertEquals('', $name); + } + + public function testReadStructEnd() + { + $transport = $this->createMock(TTransport::class); + $protocol = new TBinaryProtocol($transport, false, false); + + $this->assertEquals(0, $protocol->readStructEnd()); + } + + /** + * @dataProvider readFieldBeginDataProvider + */ + public function testReadFieldBegin( + $storedFieldType, + $readCallsParams, + $readCallsResults, + $expectedResult, + $expectedName, + $expectedFieldType, + $expectedFieldId + ) { + $transport = $this->createMock(TTransport::class); + $protocol = new TBinaryProtocol($transport, false, false); + + $transport + ->expects($this->exactly(count($readCallsParams))) + ->method('readAll') + ->withConsecutive(...$readCallsParams) + ->willReturnOnConsecutiveCalls(...$readCallsResults); + + $this->assertEquals($expectedResult, $protocol->readFieldBegin($name, $fieldType, $fieldId)); + $this->assertEquals($expectedName, $name); + $this->assertEquals($expectedFieldType, $fieldType); + $this->assertEquals($expectedFieldId, $fieldId); + } + + public function readFieldBeginDataProvider() + { + yield 'default' => [ + 'storedFieldType' => TType::STRING, + 'readCallsParams' => [ + [1], #readByte + [2], #readI16 + ], + 'readCallsResults' => [ + pack('c', TType::STRING), + pack('n', 555), + ], + 'expectedResult' => 3, + 'exprectedName' => '', + 'expectedFieldType' => TType::STRING, + 'expectedFieldId' => 555, + ]; + + yield 'stop field' => [ + 'storedFieldType' => TType::STOP, + 'readCallsParams' => [ + [1], #readByte + ], + 'readCallsResults' => [ + pack('c', TType::STOP), + ], + 'expectedResult' => 1, + 'exprectedName' => '', + 'expectedFieldType' => 0, + 'expectedFieldId' => 0, + ]; + } + + public function testReadFieldEnd() + { + $transport = $this->createMock(TTransport::class); + $protocol = new TBinaryProtocol($transport, false, false); + + $this->assertEquals(0, $protocol->readFieldEnd()); + } + + public function testReadMapBegin() + { + $transport = $this->createMock(TTransport::class); + $protocol = new TBinaryProtocol($transport, false, false); + + $transport + ->expects($this->exactly(3)) + ->method('readAll') + ->withConsecutive( + ...[ + [1], #readByte + [1], #readByte + [4], #readI32 + ] + )->willReturnOnConsecutiveCalls( + pack('c', TType::I32), + pack('c', TType::STRING), + pack('N', 555) + ); + + $this->assertEquals(6, $protocol->readMapBegin($keyType, $valType, $size)); + $this->assertEquals(TType::I32, $keyType); + $this->assertEquals(TType::STRING, $valType); + $this->assertEquals(555, $size); + } + + public function testReadMapEnd() + { + $transport = $this->createMock(TTransport::class); + $protocol = new TBinaryProtocol($transport, false, false); + + $this->assertEquals(0, $protocol->readMapEnd()); + } + + public function testReadListBegin() + { + $transport = $this->createMock(TTransport::class); + $protocol = new TBinaryProtocol($transport, false, false); + + $transport + ->expects($this->exactly(2)) + ->method('readAll') + ->withConsecutive( + ...[ + [1], #readByte + [4], #readI32 + ] + )->willReturnOnConsecutiveCalls( + pack('c', TType::I32), + pack('N', 555) + ); + + $this->assertEquals(5, $protocol->readListBegin($elemType, $size)); + $this->assertEquals(TType::I32, $elemType); + $this->assertEquals(555, $size); + } + + public function testReadListEnd() + { + $transport = $this->createMock(TTransport::class); + $protocol = new TBinaryProtocol($transport, false, false); + + $this->assertEquals(0, $protocol->readListEnd()); + } + + public function testReadSetBegin() + { + $transport = $this->createMock(TTransport::class); + $protocol = new TBinaryProtocol($transport, false, false); + + $transport + ->expects($this->exactly(2)) + ->method('readAll') + ->withConsecutive( + ...[ + [1], #readByte + [4], #readI32 + ] + )->willReturnOnConsecutiveCalls( + pack('c', TType::I32), + pack('N', 555) + ); + + $this->assertEquals(5, $protocol->readSetBegin($elemType, $size)); + $this->assertEquals(TType::I32, $elemType); + $this->assertEquals(555, $size); + } + + public function testReadSetEnd() + { + $transport = $this->createMock(TTransport::class); + $protocol = new TBinaryProtocol($transport, false, false); + + $this->assertEquals(0, $protocol->readSetEnd()); + } + + public function testReadBool() + { + $transport = $this->createMock(TTransport::class); + $protocol = new TBinaryProtocol($transport, false, false); + + $transport + ->expects($this->once()) + ->method('readAll') + ->with(1) #readByte + ->willReturn(pack('c', 1)); + + $this->assertEquals(1, $protocol->readBool($value)); + $this->assertTrue($value); + } + + public function testReadByte() + { + $transport = $this->createMock(TTransport::class); + $protocol = new TBinaryProtocol($transport, false, false); + + $transport + ->expects($this->once()) + ->method('readAll') + ->with(1) #readByte + ->willReturn(pack('c', 1)); + + $this->assertEquals(1, $protocol->readByte($value)); + $this->assertEquals(1, $value); + } + + /** + * @dataProvider readI16DataProvider + */ + public function testReadI16( + $storedValue, + $expectedValue + ) { + $transport = $this->createMock(TTransport::class); + $protocol = new TBinaryProtocol($transport, false, false); + + $transport + ->expects($this->once()) + ->method('readAll') + ->with(2) #readI16 + ->willReturn(pack('n', $storedValue)); + + $this->assertEquals(2, $protocol->readI16($value)); + $this->assertEquals($expectedValue, $value); + } + + public function readI16DataProvider() + { + yield 'positive' => [1, 1]; + yield 'negative' => [-1, -1]; + } + + /** + * @dataProvider readI16DataProvider + */ + public function testReadI32( + $storedValue, + $expectedValue + ) { + $transport = $this->createMock(TTransport::class); + $protocol = new TBinaryProtocol($transport, false, false); + + $transport + ->expects($this->once()) + ->method('readAll') + ->with(4) #readI32 + ->willReturn(pack('N', $storedValue)); + + $this->assertEquals(4, $protocol->readI32($value)); + $this->assertEquals($expectedValue, $value); + } + + public function readI32DataProvider() + { + yield 'positive' => [1, 1]; + yield 'negative' => [-1, -1]; + } + + /** + * @dataProvider readI64For32BitArchitectureDataProvider + */ + public function testReadI64For32BitArchitecture( + $storedValue, + $expectedValue + ) { + if (PHP_INT_SIZE !== 4) { + $this->markTestSkipped('Test is only for 32 bit architecture'); + } + + $transport = $this->createMock(TTransport::class); + $protocol = new TBinaryProtocol($transport, false, false); + + $neg = $storedValue < 0; + + if ($neg) { + $storedValue *= -1; + } + + $hi = (int)($storedValue / 4294967296); + $lo = (int)$storedValue; + + if ($neg) { + $hi = ~$hi; + $lo = ~$lo; + if (($lo & (int)0xffffffff) == (int)0xffffffff) { + $lo = 0; + $hi++; + } else { + $lo++; + } + } + + $transport + ->expects($this->once()) + ->method('write') + ->with(pack('N2', $hi, $lo), 8) #writeI64 + ->willReturn(4); + + $this->assertEquals(8, $protocol->readI64($value)); + $this->assertEquals($expectedValue, $value); + } + + public function readI64For32BitArchitectureDataProvider() + { + $storedValueRepresent = function ($value) { + $neg = $value < 0; + + if ($neg) { + $value *= -1; + } + + $hi = (int)($value / 4294967296); + $lo = (int)$value; + + if ($neg) { + $hi = ~$hi; + $lo = ~$lo; + if (($lo & (int)0xffffffff) == (int)0xffffffff) { + $lo = 0; + $hi++; + } else { + $lo++; + } + } + + return pack('N2', $hi, $lo); + }; + + yield 'positive' => [ + 'storedValue' => $storedValueRepresent(1), + 'expectedValue' => 1, + ]; + + yield 'max' => [ + 'storedValue' => $storedValueRepresent(PHP_INT_MAX), + 'expectedValue' => PHP_INT_MAX, + ]; + + yield 'min' => [ + 'storedValue' => $storedValueRepresent(PHP_INT_MIN), + 'expectedValue' => PHP_INT_MIN, + ]; + + yield 'negative' => [ + 'storedValue' => $storedValueRepresent(-1), + 'expectedValue' => -1, + ]; + } + + /** + * @dataProvider readI64For64BitArchitectureDataProvider + */ + public function testReadI64For64BitArchitecture( + $storedValue, + $expectedValue + ) { + if (PHP_INT_SIZE == 4) { + $this->markTestSkipped('Test is only for 64 bit architecture'); + } + $transport = $this->createMock(TTransport::class); + $protocol = new TBinaryProtocol($transport, false, false); + + $transport + ->expects($this->once()) + ->method('readAll') + ->with(8) #readI64 + ->willReturn($storedValue); + + $this->assertEquals(8, $protocol->readI64($value)); + $this->assertEquals($expectedValue, $value); + } + + public function readI64For64BitArchitectureDataProvider() + { + $storedValueRepresent = function ($value) { + $hi = $value >> 32; + $lo = $value & 0xFFFFFFFF; + + return pack('N2', $hi, $lo); + }; + + yield 'positive' => [ + 'storedValue' => $storedValueRepresent(1), + 'expectedValue' => 1, + ]; + + yield 'max' => [ + 'storedValue' => $storedValueRepresent(PHP_INT_MAX), + 'expectedValue' => PHP_INT_MAX, + ]; + + yield 'min' => [ + 'storedValue' => $storedValueRepresent(PHP_INT_MIN), + 'expectedValue' => PHP_INT_MIN, + ]; + + yield 'negative' => [ + 'storedValue' => $storedValueRepresent(-1), + 'expectedValue' => -1, + ]; + } + + public function testReadDouble() + { + $transport = $this->createMock(TTransport::class); + $protocol = new TBinaryProtocol($transport, false, false); + + $transport + ->expects($this->once()) + ->method('readAll') + ->with(8) #readDouble + ->willReturn(strrev(pack('d', 789))); + + $this->assertEquals(8, $protocol->readDouble($value)); + $this->assertEquals(789, $value); + } + + /** + * @dataProvider readStringDataProvider + */ + public function testReadString( + $readCallsParams, + $readCallsResults, + $expectedLength, + $expectedValue + ) { + $transport = $this->createMock(TTransport::class); + $protocol = new TBinaryProtocol($transport, false, false); + + $transport + ->expects($this->exactly(count($readCallsParams))) + ->method('readAll') + ->withConsecutive(...$readCallsParams) + ->willReturnOnConsecutiveCalls(...$readCallsResults); + + $this->assertEquals($expectedLength, $protocol->readString($value)); + $this->assertEquals($expectedValue, $value); + } + + public function readStringDataProvider() + { + $storedValue = ''; + yield 'empty' => [ + 'readCallsParams' => [ + [4] + ], + 'readCallsResults' => [ + pack('N', strlen($storedValue)) + ], + 'expectedLength' => 4, + 'expectedValue' => '', + ]; + + $storedValue = 'string'; + yield 'non-empty' => [ + 'readCallsParams' => [ + [4], + [strlen($storedValue)] + ], + 'readCallsResults' => [ + pack('N', strlen($storedValue)), + $storedValue + ], + 'expectedLength' => 10, + 'expectedValue' => 'string', + ]; + } +} diff --git a/lib/php/test/Unit/Lib/Protocol/TCompactProtocolTest.php b/lib/php/test/Unit/Lib/Protocol/TCompactProtocolTest.php new file mode 100644 index 00000000000..95f972cf268 --- /dev/null +++ b/lib/php/test/Unit/Lib/Protocol/TCompactProtocolTest.php @@ -0,0 +1,843 @@ +createMock(TTransport::class)); + $this->assertSame($expected, $protocol->toZigZag($n, $bits)); + } + + public function toZigZagDataProvider() + { + yield ['n' => 0, 'bits' => 16, 'expected' => 0]; + yield ['n' => -1, 'bits' => 16, 'expected' => 1]; + yield ['n' => 1, 'bits' => 16, 'expected' => 2]; + yield ['n' => -2, 'bits' => 16, 'expected' => 3]; + yield ['n' => 2, 'bits' => 16, 'expected' => 4]; + yield ['n' => -1, 'bits' => 32, 'expected' => 1]; + yield ['n' => 1, 'bits' => 32, 'expected' => 2]; + yield ['n' => -1, 'bits' => 64, 'expected' => 1]; + yield ['n' => 1, 'bits' => 64, 'expected' => 2]; + yield ['n' => -0x7fffffff, 'bits' => 64, 'expected' => 4294967293]; + yield ['n' => 0x7fffffff, 'bits' => 64, 'expected' => 4294967294]; + } + + /** + * @dataProvider fromZigZagDataProvider + */ + public function testFromZigZag( + $n, + $expected + ) { + $protocol = new TCompactProtocol($this->createMock(TTransport::class)); + $this->assertSame($expected, $protocol->fromZigZag($n)); + } + + public function fromZigZagDataProvider() + { + yield ['n' => 0, 'expected' => 0]; + yield ['n' => 1, 'expected' => -1]; + yield ['n' => 2, 'expected' => 1]; + yield ['n' => 3, 'expected' => -2]; + yield ['n' => 4, 'expected' => 2]; + yield ['n' => 4294967293, 'expected' => -0x7fffffff]; + yield ['n' => 4294967294, 'expected' => 0x7fffffff]; + } + + /** + * @dataProvider getVarintDataProvider + */ + public function testGetVarint( + $data, + $expected + ) { + $protocol = new TCompactProtocol($this->createMock(TTransport::class)); + $this->assertSame($expected, $protocol->getVarint($data)); + } + + public function getVarintDataProvider() + { + yield ['data' => 0, 'expected' => "\x00"]; + yield ['data' => 1, 'expected' => "\x01"]; + yield ['data' => 97, 'expected' => "a"]; + yield ['data' => 100, 'expected' => "d"]; + yield ['data' => 1000, 'expected' => "\xe8\x07"]; + } + + public function testWriteVarint() + { + $transport = $this->createMock(TTransport::class); + $protocol = new TCompactProtocol($transport); + + $transport->expects($this->once()) + ->method('write') + ->with("\xe8\x07", 2); + + $protocol->writeVarint(1000); + } + + public function testReadVarint() + { + $transport = $this->createMock(TTransport::class); + $protocol = new TCompactProtocol($transport); + + $transport->expects($this->exactly(2)) + ->method('readAll') + ->with(1) + ->willReturnOnConsecutiveCalls( + ...[ + "\xe8", + "\x07", + ] + ); + + $this->assertSame(2, $protocol->readVarint($result)); + $this->assertSame(1000, $result); + } + + public function testWriteMessageBegin() + { + $name = 'testName'; + $type = TType::STRING; + $seqid = 1; + + $transport = $this->createMock(TTransport::class); + $protocol = new TCompactProtocol($transport); + + $transport + ->expects($this->exactly(5)) + ->method('write') + ->withConsecutive( + ...[ + [pack('C', self::PROTOCOL_ID), 1], #protocal id + [pack('C', self::VERSION | ($type << TCompactProtocol::TYPE_SHIFT_AMOUNT)), 1], #version + ["\x01", 1], #seqid + ["\x08", 1], #field name length + ["testName", 8], #field name + ] + )->willReturnOnConsecutiveCalls( + 1, + 1, + 1, + 1, + 8 + ); + + $result = $protocol->writeMessageBegin($name, $type, $seqid); + $this->assertSame(12, $result); + + $ref = new \ReflectionClass($protocol); + $state = $ref->getProperty('state'); + $state->setAccessible(true); + $this->assertSame(self::STATE_VALUE_WRITE, $state->getValue($protocol)); + } + + public function testWriteMessageEnd() + { + $transport = $this->createMock(TTransport::class); + $protocol = new TCompactProtocol($transport); + + $this->assertSame(0, $protocol->writeMessageEnd()); + $ref = new \ReflectionClass($protocol); + $state = $ref->getProperty('state'); + $state->setAccessible(true); + $this->assertSame(self::STATE_CLEAR, $state->getValue($protocol)); + } + + public function testWriteStruct() + { + $name = 'testName'; + + $transport = $this->createMock(TTransport::class); + $protocol = new TCompactProtocol($transport); + $ref = new \ReflectionClass($protocol); + $state = $ref->getProperty('state'); + $state->setAccessible(true); + $lastFid = $ref->getProperty('lastFid'); + $lastFid->setAccessible(true); + $structs = $ref->getProperty('structs'); + $structs->setAccessible(true); + + $this->assertSame(0, $protocol->writeStructBegin($name)); + $this->assertSame([[self::STATE_CLEAR, 0]], $structs->getValue($protocol)); + $this->assertSame(self::STATE_FIELD_WRITE, $state->getValue($protocol)); + $this->assertSame(0, $lastFid->getValue($protocol)); + + $this->assertSame(0, $protocol->writeStructBegin($name)); + $this->assertSame(self::STATE_FIELD_WRITE, $state->getValue($protocol)); + $this->assertSame(0, $lastFid->getValue($protocol)); + $this->assertSame([[self::STATE_CLEAR, 0], [self::STATE_FIELD_WRITE, 0]], $structs->getValue($protocol)); + + $this->assertSame(0, $protocol->writeStructEnd()); + $this->assertSame(self::STATE_FIELD_WRITE, $state->getValue($protocol)); + $this->assertSame(0, $lastFid->getValue($protocol)); + $this->assertSame([[self::STATE_CLEAR, 0]], $structs->getValue($protocol)); + + $this->assertSame(0, $protocol->writeStructEnd()); + $this->assertSame(self::STATE_CLEAR, $state->getValue($protocol)); + $this->assertSame(0, $lastFid->getValue($protocol)); + $this->assertSame([], $structs->getValue($protocol)); + } + + public function testWriteFieldStop() + { + $transport = $this->createMock(TTransport::class); + $protocol = new TCompactProtocol($transport); + + $transport->expects($this->once()) + ->method('write') + ->with("\x00", 1); + + $this->assertSame(1, $protocol->writeFieldStop()); + } + + /** + * @dataProvider writeFieldHeaderDataProvider + */ + public function testWriteFieldHeader( + $type, + $fid, + $writeCallParams, + $writeCallResult, + $expectedResult + ) { + $transport = $this->createMock(TTransport::class); + $protocol = new TCompactProtocol($transport); + + $transport + ->expects($this->exactly(count($writeCallParams))) + ->method('write') + ->withConsecutive(...$writeCallParams) + ->willReturnOnConsecutiveCalls(...$writeCallResult); + + $this->assertSame($expectedResult, $protocol->writeFieldHeader($type, $fid)); + } + + public function writeFieldHeaderDataProvider() + { + yield 'bool' => [ + 'type' => TType::BOOL, + 'fid' => 1, + 'writeCallParams' => [ + ["\x12", 1], #writeUByte(pack('C', ($delta << 4) | $type)), + ], + 'writeCallResult' => [ + 1, + ], + 'expectedResult' => 1, + ]; + yield 'list' => [ + 'type' => TType::LST, + 'fid' => 16, + 'writeCallParams' => [ + ["\x0f", 1], #writeUByte(pack('C', ($delta << 4) | $type)), + [" ", 1], #writeI16($fid), + ], + 'writeCallResult' => [ + 1, + ], + 'expectedResult' => 2, + ]; + } + + /** + * @dataProvider writeFieldBeginDataProvider + */ + public function testWriteFieldBegin( + $fieldName, + $fieldType, + $fieldId, + $writeCallParams, + $writeCallResult, + $expectedState, + $expectedBoolFid, + $expectedLastFid, + $expectedResult + ) { + $transport = $this->createMock(TTransport::class); + $protocol = new TCompactProtocol($transport); + + $transport + ->expects($this->exactly(count($writeCallParams))) + ->method('write') + ->withConsecutive(...$writeCallParams) + ->willReturnOnConsecutiveCalls(...$writeCallResult); + + $this->assertSame($expectedResult, $protocol->writeFieldBegin($fieldName, $fieldType, $fieldId)); + + $ref = new \ReflectionClass($protocol); + $state = $ref->getProperty('state'); + $state->setAccessible(true); + $boolFid = $ref->getProperty('boolFid'); + $boolFid->setAccessible(true); + $lastFid = $ref->getProperty('lastFid'); + $lastFid->setAccessible(true); + $this->assertSame($expectedState, $state->getValue($protocol)); + $this->assertSame($expectedBoolFid, $boolFid->getValue($protocol)); + $this->assertSame($expectedLastFid, $lastFid->getValue($protocol)); + } + + public function writeFieldBeginDataProvider() + { + yield 'bool' => [ + 'fieldName' => 'testName', + 'fieldType' => TType::BOOL, + 'fieldId' => 1, + 'writeCallParams' => [], + 'writeCallResult' => [], + 'expectedState' => self::STATE_BOOL_WRITE, + 'expectedBoolFid' => 1, + 'expectedLastFid' => 0, + 'expectedResult' => 0, + ]; + yield 'list' => [ + 'fieldName' => 'testName', + 'fieldType' => TType::LST, + 'fieldId' => 1, + 'writeCallParams' => [ + ["\x19", 1], #writeUByte(pack('C', ($delta << 4) | $type)), + ], + 'writeCallResult' => [ + 1, + ], + 'expectedState' => self::STATE_VALUE_WRITE, + 'expectedBoolFid' => null, + 'expectedLastFid' => 1, + 'expectedResult' => 1, + ]; + } + + public function testWriteFieldEnd() + { + $transport = $this->createMock(TTransport::class); + $protocol = new TCompactProtocol($transport); + + $this->assertSame(0, $protocol->writeFieldEnd()); + + $ref = new \ReflectionClass($protocol); + $state = $ref->getProperty('state'); + $state->setAccessible(true); + $this->assertSame(self::STATE_FIELD_WRITE, $state->getValue($protocol)); + } + + /** + * @dataProvider writeCollectionDataProvider + */ + public function testWriteCollection( + $etype, + $size, + $writeCallParams, + $writeCallResult, + $expectedState, + $expectedContainers, + $expectedResult + ) { + $transport = $this->createMock(TTransport::class); + $protocol = new TCompactProtocol($transport); + + $transport + ->expects($this->exactly(count($writeCallParams))) + ->method('write') + ->withConsecutive(...$writeCallParams) + ->willReturnOnConsecutiveCalls(...$writeCallResult); + + $this->assertSame($expectedResult, $protocol->writeCollectionBegin($etype, $size)); + + $ref = new \ReflectionClass($protocol); + $state = $ref->getProperty('state'); + $state->setAccessible(true); + $containers = $ref->getProperty('containers'); + $containers->setAccessible(true); + $this->assertSame($expectedState, $state->getValue($protocol)); + $this->assertSame($expectedContainers, $containers->getValue($protocol)); + + $this->assertSame(0, $protocol->writeCollectionEnd()); + $this->assertSame(TCompactProtocol::STATE_CLEAR, $state->getValue($protocol)); + } + + public function writeCollectionDataProvider() + { + yield 'size < 14' => [ + 'etype' => TType::STRING, + 'size' => 1, + 'writeCallParams' => [ + ["\x18", 1], #writeUByte(pack('C', ($size << 4 | self::$ctypes[$etype])), + ], + 'writeCallResult' => [ + 1, + ], + 'expectedState' => self::STATE_CONTAINER_WRITE, + 'expectedContainers' => [ + 0 => 0, + ], + 'expectedResult' => 1, + ]; + yield 'size > 14' => [ + 'etype' => TType::STRING, + 'size' => 16, + 'writeCallParams' => [ + ["\xf8", 1], #writeUByte(pack('C', 0xf0 | self::$ctypes[$etype])), + ["\x10", 1], #writeVarint(16), + ], + 'writeCallResult' => [ + 1, + 1, + ], + 'expectedState' => self::STATE_CONTAINER_WRITE, + 'expectedContainers' => [ + 0 => 0, + ], + 'expectedResult' => 2, + ]; + } + + /** + * @dataProvider writeMapDataProvider + */ + public function testWriteMap( + $keyType, + $valType, + $size, + $writeCallParams, + $writeCallResult, + $expectedContainers, + $expectedResult + ) { + $transport = $this->createMock(TTransport::class); + $protocol = new TCompactProtocol($transport); + + $transport + ->expects($this->exactly(count($writeCallParams))) + ->method('write') + ->withConsecutive(...$writeCallParams) + ->willReturnOnConsecutiveCalls(...$writeCallResult); + + $this->assertSame($expectedResult, $protocol->writeMapBegin($keyType, $valType, $size)); + + $ref = new \ReflectionClass($protocol); + $containers = $ref->getProperty('containers'); + $containers->setAccessible(true); + $state = $ref->getProperty('state'); + $state->setAccessible(true); + $this->assertSame($expectedContainers, $containers->getValue($protocol)); + $this->assertSame(TCompactProtocol::STATE_CLEAR, $state->getValue($protocol)); + + $this->assertSame(0, $protocol->writeMapEnd()); + $this->assertSame(TCompactProtocol::STATE_CLEAR, $state->getValue($protocol)); + $this->assertSame([], $containers->getValue($protocol)); + } + + public function writeMapDataProvider() + { + yield 'size zero' => [ + 'keyType' => TType::STRING, + 'valType' => TType::STRING, + 'size' => 0, + 'writeCallParams' => [ + ["\x00", 1], #writeByte(0), + ], + 'writeCallResult' => [ + 1, + ], + 'expectedContainers' => [ + 0 => 0, + ], + 'expectedResult' => 1, + ]; + yield 'size non zero' => [ + 'keyType' => TType::STRING, + 'valType' => TType::STRING, + 'size' => 16, + 'writeCallParams' => [ + ["\x10", 1], #writeVarint(16), + ["\x88", 1], #writeUByte(pack('C', self::$ctypes[$key_type] << 4 | self::$ctypes[$val_type])), + ], + 'writeCallResult' => [ + 1, + 1, + ], + 'expectedContainers' => [ + 0 => 0, + ], + 'expectedResult' => 2, + ]; + } + + public function testWriteListBegin() + { + $protocol = $this->createPartialMock(TCompactProtocol::class, ['writeCollectionBegin']); + + $protocol->expects($this->once()) + ->method('writeCollectionBegin') + ->with(TType::STRING, 1) + ->willReturn(1); + + $this->assertSame(1, $protocol->writeListBegin(TType::STRING, 1)); + } + + public function testWriteListEnd() + { + $protocol = $this->createPartialMock(TCompactProtocol::class, ['writeCollectionEnd']); + + $protocol->expects($this->once()) + ->method('writeCollectionEnd') + ->willReturn(1); + + $this->assertSame(1, $protocol->writeListEnd()); + } + + public function testWriteSettBegin() + { + $protocol = $this->createPartialMock(TCompactProtocol::class, ['writeCollectionBegin']); + + $protocol->expects($this->once()) + ->method('writeCollectionBegin') + ->with(TType::STRING, 1) + ->willReturn(1); + + $this->assertSame(1, $protocol->writeSetBegin(TType::STRING, 1)); + } + + public function testWriteSetEnd() + { + $protocol = $this->createPartialMock(TCompactProtocol::class, ['writeCollectionEnd']); + + $protocol->expects($this->once()) + ->method('writeCollectionEnd') + ->willReturn(1); + + $this->assertSame(1, $protocol->writeSetEnd()); + } + + /** + * @dataProvider writeBinaryDataProvider + */ + public function testWriteBool( + $value, + $startState, + $writeCallParams, + $writeCallResult, + $expectedResult, + $expectedException, + $expectedExceptionMessage + ) { + if ($expectedException) { + $this->expectException($expectedException); + $this->expectExceptionMessage($expectedExceptionMessage); + } + + $transport = $this->createMock(TTransport::class); + $protocol = new TCompactProtocol($transport); + if (!is_null($startState)) { + $ref = new \ReflectionClass($protocol); + $state = $ref->getProperty('state'); + $state->setAccessible(true); + $state->setValue($protocol, $startState); + } + + $transport + ->expects($this->exactly(count($writeCallParams))) + ->method('write') + ->withConsecutive(...$writeCallParams) + ->willReturnOnConsecutiveCalls(...$writeCallResult); + + $this->assertSame($expectedResult, $protocol->writeBool($value)); + } + + public function writeBinaryDataProvider() + { + yield 'invalid state' => [ + 'value' => true, + 'startState' => null, + 'writeCallParams' => [], + 'writeCallResult' => [], + 'expectedResult' => 0, + 'expectedException' => TProtocolException::class, + 'expectedExceptionMessage' => 'Invalid state in compact protocol', + ]; + + yield 'true' => [ + 'value' => true, + 'startState' => TCompactProtocol::STATE_BOOL_WRITE, + 'writeCallParams' => [ + ["\x01", 1], #writeByte + ["\x00", 1], #writeI16 + ], + 'writeCallResult' => [ + 1, + 1, + ], + 'expectedResult' => 2, + 'expectedException' => null, + 'expectedExceptionMessage' => null, + ]; + + yield 'false' => [ + 'value' => false, + 'startState' => TCompactProtocol::STATE_BOOL_WRITE, + 'writeCallParams' => [ + ["\x02", 1], #writeByte + ["\x00", 1], #writeI16 + ], + 'writeCallResult' => [ + 1, + 1, + ], + 'expectedResult' => 2, + 'expectedException' => null, + 'expectedExceptionMessage' => null, + ]; + + yield 'container true' => [ + 'value' => true, + 'startState' => TCompactProtocol::STATE_CONTAINER_WRITE, + 'writeCallParams' => [ + ["\x01", 1], #writeByte + ], + 'writeCallResult' => [ + 1, + ], + 'expectedResult' => 1, + 'expectedException' => null, + 'expectedExceptionMessage' => null, + ]; + } + + /** + * @dataProvider writeByteDataProvider + */ + public function testWriteByte( + $value, + $expectedWriteCallParam + ) { + $transport = $this->createMock(TTransport::class); + $protocol = new TCompactProtocol($transport); + + $transport->expects($this->once()) + ->method('write') + ->with($expectedWriteCallParam, 1); + + $this->assertSame(1, $protocol->writeByte($value)); + } + + public function writeByteDataProvider() + { + yield 'signed' => [ + 'value' => -1, + 'expectedWriteCallParam' => "\xff", + ]; + yield 'unsigned' => [ + 'value' => 1, + 'expectedWriteCallParam' => "\x01", + ]; + yield 'lowercase' => [ + 'value' => 'a', + 'expectedWriteCallParam' => "\x00", + ]; + yield 'upercase' => [ + 'value' => 'A', + 'expectedWriteCallParam' => "\x00", + ]; + } + + /** + * @dataProvider writeUByteDataProvider + */ + public function testWriteUByte( + $value, + $expectedWriteCallParam + ) { + $transport = $this->createMock(TTransport::class); + $protocol = new TCompactProtocol($transport); + + $transport->expects($this->once()) + ->method('write') + ->with($expectedWriteCallParam, 1); + + $this->assertSame(1, $protocol->writeUByte($value)); + } + + public function writeUByteDataProvider() + { + yield 'signed' => [ + 'value' => -1, + 'expectedWriteCallParam' => "\xff", + ]; + yield 'unsigned' => [ + 'value' => 1, + 'expectedWriteCallParam' => "\x01", + ]; + yield 'lowercase' => [ + 'value' => 'a', + 'expectedWriteCallParam' => "\x00", + ]; + yield 'upercase' => [ + 'value' => 'A', + 'expectedWriteCallParam' => "\x00", + ]; + } + + public function testWriteI16() + { + $transport = $this->createMock(TTransport::class); + $protocol = new TCompactProtocol($transport); + + $transport->expects($this->once()) + ->method('write') + ->with("\x00", 1); + + $this->assertSame(1, $protocol->writeI16(0)); + } + + public function testWriteI32() + { + $transport = $this->createMock(TTransport::class); + $protocol = new TCompactProtocol($transport); + + $transport->expects($this->once()) + ->method('write') + ->with("\x00", 1); + + $this->assertSame(1, $protocol->writeI32(0)); + } + + public function testWriteDouble() + { + $transport = $this->createMock(TTransport::class); + $protocol = new TCompactProtocol($transport); + + $transport->expects($this->once()) + ->method('write') + ->with(pack('d', 0), 8); + + $this->assertSame(8, $protocol->writeDouble(0)); + } + + public function testWriteString() + { + $transport = $this->createMock(TTransport::class); + $protocol = new TCompactProtocol($transport); + + $transport->expects($this->exactly(2)) + ->method('write') + ->withConsecutive( + ["\x04", 1], + ["test", 4] + ); + + $this->assertSame(5, $protocol->writeString('test')); + } + + /** + * @dataProvider writeI64DataProvider + */ + public function testWriteI64( + $value, + $expectedWriteCallParam, + $expectedResult + ) { + $transport = $this->createMock(TTransport::class); + $protocol = new TCompactProtocol($transport); + + $transport->expects($this->once()) + ->method('write') + ->with(...$expectedWriteCallParam); + + $this->assertSame($expectedResult, $protocol->writeI64($value)); + } + + public function writeI64DataProvider() + { + yield 'simple' => [ + 'value' => 0, + 'expectedWriteCallParam' => ["\x00", 1], + 'expectedResult' => 1, + ]; + yield 'negative' => [ + 'value' => -1, + 'expectedWriteCallParam' => ["\x01", 1], + 'expectedResult' => 1, + ]; + yield 'big' => [ + 'value' => 5000000000, + 'expectedWriteCallParam' => [hex2bin("80c8afa025"), 5], + 'expectedResult' => 5, + ]; + yield 'small' => [ + 'value' => -5000000000, + 'expectedWriteCallParam' => [hex2bin("ffc7afa025"), 5], + 'expectedResult' => 5, + ]; + yield 'max simple' => [ + 'value' => 0xffffffff, + 'expectedWriteCallParam' => [hex2bin("feffffff1f"), 5], + 'expectedResult' => 5, + ]; + } +} diff --git a/lib/php/test/Unit/Lib/Protocol/TMultiplexedProtocolTest.php b/lib/php/test/Unit/Lib/Protocol/TMultiplexedProtocolTest.php new file mode 100644 index 00000000000..970e3a946c6 --- /dev/null +++ b/lib/php/test/Unit/Lib/Protocol/TMultiplexedProtocolTest.php @@ -0,0 +1,85 @@ +createMock(TProtocol::class); + $multiplexedProtocol = new TMultiplexedProtocol($protocol, $serviceName); + + $protocol->expects($this->once()) + ->method('writeMessageBegin') + ->with($expectedName, $type, $seqid); + + $multiplexedProtocol->writeMessageBegin($name, $type, $seqid); + } + + public function writeMessageBeginDataProvider() + { + yield 'messageTypeCall' => [ + 'serviceName' => 'serviceName', + 'name' => 'testName', + 'type' => TMessageType::CALL, + 'seqid' => 1, + 'expectedName' => 'serviceName:testName' + ]; + yield 'messageTypeOneWay' => [ + 'serviceName' => 'serviceName', + 'name' => 'testName', + 'type' => TMessageType::ONEWAY, + 'seqid' => 1, + 'expectedName' => 'serviceName:testName' + ]; + yield 'messageTypeReply' => [ + 'serviceName' => 'serviceName', + 'name' => 'testName', + 'type' => TMessageType::REPLY, + 'seqid' => 1, + 'expectedName' => 'testName' + ]; + yield 'messageTypeException' => [ + 'serviceName' => 'serviceName', + 'name' => 'testName', + 'type' => TMessageType::EXCEPTION, + 'seqid' => 1, + 'expectedName' => 'testName' + ]; + + } +} diff --git a/lib/php/test/Unit/Lib/Protocol/TProtocolDecoratorTest.php b/lib/php/test/Unit/Lib/Protocol/TProtocolDecoratorTest.php new file mode 100644 index 00000000000..e5dbdb36b29 --- /dev/null +++ b/lib/php/test/Unit/Lib/Protocol/TProtocolDecoratorTest.php @@ -0,0 +1,96 @@ +createMock(TProtocol::class); + $decorator = new class ($concreteProtocol) extends TProtocolDecorator { + public function __construct(TProtocol $protocol) + { + parent::__construct($protocol); + } + }; + + $concreteProtocol->expects($this->once()) + ->method($methodName) + ->with(...$methodArguments); + + $decorator->$methodName(...$methodArguments); + } + + public function methodDecorationDataProvider() + { + yield 'writeMessageBegin' => ['writeMessageBegin', ['name', 'type', 'seqid']]; + yield 'writeMessageEnd' => ['writeMessageEnd', []]; + yield 'writeStructBegin' => ['writeStructBegin', ['name']]; + yield 'writeStructEnd' => ['writeStructEnd', []]; + yield 'writeFieldBegin' => ['writeFieldBegin', ['name', 'type', 'id']]; + yield 'writeFieldEnd' => ['writeFieldEnd', []]; + yield 'writeFieldStop' => ['writeFieldStop', []]; + yield 'writeMapBegin' => ['writeMapBegin', ['keyType', 'valType', 'size']]; + yield 'writeMapEnd' => ['writeMapEnd', []]; + yield 'writeListBegin' => ['writeListBegin', ['elemType', 'size']]; + yield 'writeListEnd' => ['writeListEnd', []]; + yield 'writeSetBegin' => ['writeSetBegin', ['elemType', 'size']]; + yield 'writeSetEnd' => ['writeSetEnd', []]; + yield 'writeBool' => ['writeBool', ['value']]; + yield 'writeByte' => ['writeByte', ['value']]; + yield 'writeI16' => ['writeI16', ['value']]; + yield 'writeI32' => ['writeI32', ['value']]; + yield 'writeI64' => ['writeI64', ['value']]; + yield 'writeDouble' => ['writeDouble', ['value']]; + yield 'writeString' => ['writeString', ['value']]; + yield 'readMessageBegin' => ['readMessageBegin', ['name', 'type', 'seqid']]; + yield 'readMessageEnd' => ['readMessageEnd', []]; + yield 'readStructBegin' => ['readStructBegin', ['name']]; + yield 'readStructEnd' => ['readStructEnd', []]; + yield 'readFieldBegin' => ['readFieldBegin', ['name', 'type', 'id']]; + yield 'readFieldEnd' => ['readFieldEnd', []]; + yield 'readMapBegin' => ['readMapBegin', ['keyType', 'valType', 'size']]; + yield 'readMapEnd' => ['readMapEnd', []]; + yield 'readListBegin' => ['readListBegin', ['elemType', 'size']]; + yield 'readListEnd' => ['readListEnd', []]; + yield 'readSetBegin' => ['readSetBegin', ['elemType', 'size']]; + yield 'readSetEnd' => ['readSetEnd', []]; + yield 'readBool' => ['readBool', ['value']]; + yield 'readByte' => ['readByte', ['value']]; + yield 'readI16' => ['readI16', ['value']]; + yield 'readI32' => ['readI32', ['value']]; + yield 'readI64' => ['readI64', ['value']]; + yield 'readDouble' => ['readDouble', ['value']]; + yield 'readString' => ['readString', ['value']]; + } +} diff --git a/lib/php/test/Unit/Lib/Protocol/TSimpleJSONProtocolTest.php b/lib/php/test/Unit/Lib/Protocol/TSimpleJSONProtocolTest.php new file mode 100644 index 00000000000..e4d005a45ae --- /dev/null +++ b/lib/php/test/Unit/Lib/Protocol/TSimpleJSONProtocolTest.php @@ -0,0 +1,133 @@ +expectException(TException::class); + $this->expectExceptionMessage("Not implemented"); + + $transport = $this->createMock(TTransport::class); + $protocol = new TSimpleJSONProtocol($transport); + $protocol->$methodName(...$methodArguments); + } + + public function readDataProvider() + { + yield 'readMessageBegin' => [ + 'methodName' => 'readMessageBegin', + 'methodArguments' => ['name', 'type', 'seqId'], + ]; + yield 'readMessageEnd' => [ + 'methodName' => 'readMessageEnd', + 'methodArguments' => [], + ]; + yield 'readStructBegin' => [ + 'methodName' => 'readStructBegin', + 'methodArguments' => ['name'], + ]; + yield 'readStructEnd' => [ + 'methodName' => 'readStructEnd', + 'methodArguments' => [], + ]; + yield 'readFieldBegin' => [ + 'methodName' => 'readFieldBegin', + 'methodArguments' => ['name', TType::STRING, 1], + ]; + yield 'readFieldEnd' => [ + 'methodName' => 'readFieldEnd', + 'methodArguments' => [], + ]; + yield 'readMapBegin' => [ + 'methodName' => 'readMapBegin', + 'methodArguments' => [TType::STRING, TType::STRING, 1], + ]; + yield 'readMapEnd' => [ + 'methodName' => 'readMapEnd', + 'methodArguments' => [], + ]; + yield 'readListBegin' => [ + 'methodName' => 'readListBegin', + 'methodArguments' => [TType::STRING, 1], + ]; + yield 'readListEnd' => [ + 'methodName' => 'readListEnd', + 'methodArguments' => [], + ]; + yield 'readSetBegin' => [ + 'methodName' => 'readSetBegin', + 'methodArguments' => [TType::STRING, 1], + ]; + yield 'readSetEnd' => [ + 'methodName' => 'readSetEnd', + 'methodArguments' => [], + ]; + yield 'readBool' => [ + 'methodName' => 'readBool', + 'methodArguments' => [true], + ]; + yield 'readByte' => [ + 'methodName' => 'readByte', + 'methodArguments' => [0x01], + ]; + yield 'readI16' => [ + 'methodName' => 'readI16', + 'methodArguments' => [1], + ]; + yield 'readI32' => [ + 'methodName' => 'readI32', + 'methodArguments' => [1], + ]; + yield 'readI64' => [ + 'methodName' => 'readI64', + 'methodArguments' => [1], + ]; + yield 'readDouble' => [ + 'methodName' => 'readDouble', + 'methodArguments' => [0.1], + ]; + yield 'readString' => [ + 'methodName' => 'readString', + 'methodArguments' => ['string'], + ]; + } +} diff --git a/lib/php/test/Unit/Lib/Serializer/TBinarySerializerTest.php b/lib/php/test/Unit/Lib/Serializer/TBinarySerializerTest.php new file mode 100644 index 00000000000..292f261892c --- /dev/null +++ b/lib/php/test/Unit/Lib/Serializer/TBinarySerializerTest.php @@ -0,0 +1,38 @@ +markTestIncomplete('Could not test static function which create instances during execution'); + } + + public function testDeserialize() + { + $this->markTestIncomplete('Could not test static function which create instances during execution'); + } +} diff --git a/lib/php/test/Unit/Lib/Server/Fixture/TestProcessor.php b/lib/php/test/Unit/Lib/Server/Fixture/TestProcessor.php new file mode 100644 index 00000000000..8fc689194a5 --- /dev/null +++ b/lib/php/test/Unit/Lib/Server/Fixture/TestProcessor.php @@ -0,0 +1,30 @@ +markTestSkipped('Unit test could not be written for class which use pcntl_fork and exit functions'); + } +} diff --git a/lib/php/test/Unit/Lib/Server/TSSLServerSocketTest.php b/lib/php/test/Unit/Lib/Server/TSSLServerSocketTest.php new file mode 100644 index 00000000000..02ae584db42 --- /dev/null +++ b/lib/php/test/Unit/Lib/Server/TSSLServerSocketTest.php @@ -0,0 +1,150 @@ +assertEquals('ssl://localhost', $socket->getSSLHost('localhost')); + $this->assertEquals('ssl://localhost', $socket->getSSLHost('ssl://localhost')); + $this->assertEquals('tcp://localhost', $socket->getSSLHost('tcp://localhost')); + } + + public function testListenAndClose(): void + { + $options = [ + 'ssl' => [ + 'verify_peer' => true, + 'verify_peer_name' => true, + 'allow_self_signed' => true, + ], + ]; + $context = stream_context_create($options); + $socket = new TSSLServerSocket('somehost', 999, $context); + + $listener = tmpfile(); + $this->getFunctionMock('Thrift\Server', 'stream_socket_server') + ->expects($this->once()) + ->with( + 'ssl://somehost:999', #$address + $this->anything(), #&$error_code + $this->anything(), #&$error_string + STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, #int $flags + $this->callback(function ($context) use ($options) { + $contextOptions = stream_context_get_options($context); + + return is_resource($context) && $options === $contextOptions; + })#resource $context + )->willReturn($listener); + + $socket->listen(); + + $reflection = new \ReflectionClass($socket); + $property = $reflection->getProperty('listener_'); + $property->setAccessible(true); + + $this->assertIsResource($property->getValue($socket)); + + $this->getFunctionMock('Thrift\Server', 'fclose') + ->expects($this->once()) + ->with($this->equalTo($listener)) + ->willReturn(true); + + $socket->close(); + $this->assertNull($property->getValue($socket)); + } + + public function testAccept() + { + $socket = new TSSLServerSocket('somehost', 999); + $socket->setAcceptTimeout(1000); + + $listener = tmpfile(); + $this->getFunctionMock('Thrift\Server', 'stream_socket_server') + ->expects($this->once()) + ->with( + 'ssl://somehost:999', #$address + $this->anything(), #&$error_code + $this->anything(), #&$error_string + STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, #int $flags + $this->callback(function ($context) { + $contextOptions = stream_context_get_options($context); + + return is_resource($context) && $contextOptions === []; + }) #resource $context + )->willReturn($listener); + + $transportHandle = tmpfile(); + $this->getFunctionMock('Thrift\Server', 'stream_socket_accept') + ->expects($this->once()) + ->with( + $this->equalTo($listener), + 1 + )->willReturn($transportHandle); + + $socket->listen(); + $result = $socket->accept(); + $this->assertInstanceOf(TSocket::class, $result); + + $reflection = new \ReflectionClass($result); + $property = $reflection->getProperty('handle_'); + $property->setAccessible(true); + $this->assertEquals($transportHandle, $property->getValue($result)); + } + + public function testAcceptFailed() + { + $socket = new TSSLServerSocket('somehost', 999); + $socket->setAcceptTimeout(1000); + + $listener = tmpfile(); + + $this->getFunctionMock('Thrift\Server', 'stream_socket_server') + ->expects($this->once()) + ->with('ssl://somehost:999') + ->willReturn($listener); + + $this->getFunctionMock('Thrift\Server', 'stream_socket_accept') + ->expects($this->once()) + ->with( + $this->equalTo($listener), + 1 + )->willReturn(null); + + $this->expectException(TTransportException::class); + $this->expectExceptionMessage('accept() may not return NULL'); + + $socket->listen(); + $socket->accept(); + } +} diff --git a/lib/php/test/Unit/Lib/Server/TServerSocketTest.php b/lib/php/test/Unit/Lib/Server/TServerSocketTest.php new file mode 100644 index 00000000000..e9d3b9666f5 --- /dev/null +++ b/lib/php/test/Unit/Lib/Server/TServerSocketTest.php @@ -0,0 +1,128 @@ +setAcceptTimeout(1000); + + $reflection = new \ReflectionClass($socket); + $property = $reflection->getProperty('acceptTimeout_'); + $property->setAccessible(true); + + $this->assertEquals(1000, $property->getValue($socket)); + } + + public function testListenAndClose(): void + { + $socket = new TServerSocket('somehost', 999); + + $listener = tmpfile(); + $this->getFunctionMock('Thrift\Server', 'stream_socket_server') + ->expects($this->once()) + ->with('tcp://somehost:999') + ->willReturn($listener); + + $socket->listen(); + + $reflection = new \ReflectionClass($socket); + $property = $reflection->getProperty('listener_'); + $property->setAccessible(true); + + $this->assertIsResource($property->getValue($socket)); + + $this->getFunctionMock('Thrift\Server', 'fclose') + ->expects($this->once()) + ->with($this->equalTo($listener)) + ->willReturn(true); + + $socket->close(); + $this->assertNull($property->getValue($socket)); + } + + public function testAccept() + { + $socket = new TServerSocket('somehost', 999); + $socket->setAcceptTimeout(1000); + + $listener = tmpfile(); + + $this->getFunctionMock('Thrift\Server', 'stream_socket_server') + ->expects($this->once()) + ->with('tcp://somehost:999') + ->willReturn($listener); + + $transportHandle = tmpfile(); + $this->getFunctionMock('Thrift\Server', 'stream_socket_accept') + ->expects($this->once()) + ->with( + $this->equalTo($listener), + 1 + )->willReturn($transportHandle); + + $socket->listen(); + $result = $socket->accept(); + $this->assertInstanceOf(TSocket::class, $result); + + $reflection = new \ReflectionClass($result); + $property = $reflection->getProperty('handle_'); + $property->setAccessible(true); + $this->assertEquals($transportHandle, $property->getValue($result)); + } + + public function testAcceptFailed() + { + $socket = new TServerSocket('somehost', 999); + $socket->setAcceptTimeout(1000); + + $listener = tmpfile(); + + $this->getFunctionMock('Thrift\Server', 'stream_socket_server') + ->expects($this->once()) + ->with('tcp://somehost:999') + ->willReturn($listener); + + $this->getFunctionMock('Thrift\Server', 'stream_socket_accept') + ->expects($this->once()) + ->with( + $this->equalTo($listener), + 1 + )->willReturn(null); + + $this->expectException(TTransportException::class); + $this->expectExceptionMessage('accept() may not return NULL'); + + $socket->listen(); + $socket->accept(); + } +} diff --git a/lib/php/test/Unit/Lib/Server/TSimpleServerTest.php b/lib/php/test/Unit/Lib/Server/TSimpleServerTest.php new file mode 100644 index 00000000000..269b838592d --- /dev/null +++ b/lib/php/test/Unit/Lib/Server/TSimpleServerTest.php @@ -0,0 +1,166 @@ +processor = $this->createMock(TestProcessor::class); + $this->transport = $this->createMock(TServerTransport::class); + $this->inputTransportFactory = $this->createMock(TTransportFactoryInterface::class); + $this->outputTransportFactory = $this->createMock(TTransportFactoryInterface::class); + $this->inputProtocolFactory = $this->createMock(TProtocolFactory::class); + $this->outputProtocolFactory = $this->createMock(TProtocolFactory::class); + + $this->server = new TSimpleServer( + $this->processor, + $this->transport, + $this->inputTransportFactory, + $this->outputTransportFactory, + $this->inputProtocolFactory, + $this->outputProtocolFactory + ); + } + + protected function tearDown(): void + { + unset( + $this->processor, + $this->transport, + $this->inputTransportFactory, + $this->outputTransportFactory, + $this->inputProtocolFactory, + $this->outputProtocolFactory, + $this->server + ); + } + + /** + * @dataProvider serveDataProvider + */ + public function testServe( + $serveLoopCount, + array $processLoopResult + ): void { + $transport = $this->createMock(TTransport::class); + + $this->transport->expects($this->once()) + ->method('listen'); + $this->transport->expects($this->exactly($serveLoopCount)) + ->method('accept') + ->willReturn($transport); + + $this->inputTransportFactory->expects($this->exactly($serveLoopCount)) + ->method('getTransport') + ->willReturn($this->createMock(TServerTransport::class)); + $this->outputTransportFactory->expects($this->exactly($serveLoopCount)) + ->method('getTransport') + ->willReturn($this->createMock(TServerTransport::class)); + + $inputProtocol = $this->createMock(TServerTransport::class); + $this->inputProtocolFactory->expects($this->exactly($serveLoopCount)) + ->method('getProtocol') + ->willReturn($inputProtocol); + + $outputProtocol = $this->createMock(TServerTransport::class); + $this->outputProtocolFactory->expects($this->exactly($serveLoopCount)) + ->method('getProtocol') + ->willReturn($outputProtocol); + + /** + * ATTENTION! + * it is a hack to stop the server loop in unit test + * last call of process can return any value, but should stop server for removing infinite loop + **/ + $processLoopResult[] = $this->returnCallback(function () { + $this->server->stop(); + + return false; + }); + + $this->processor->expects($this->exactly(count($processLoopResult))) + ->method('process') + ->with( + $this->equalTo($inputProtocol), + $this->equalTo($outputProtocol) + ) + ->willReturnOnConsecutiveCalls(...$processLoopResult); + + $this->server->serve(); + } + + public function serveDataProvider() + { + yield 'one serve loop' => [ + 'serveLoopCount' => 1, + 'processLoopResult' => [ + true, + ] + ]; + yield 'two serve loop' => [ + 'serveLoopCount' => 2, + 'processLoopResult' => [ + true, + false, + ] + ]; + } +} diff --git a/lib/php/test/Unit/Lib/StringFunc/CoreTest.php b/lib/php/test/Unit/Lib/StringFunc/CoreTest.php new file mode 100644 index 00000000000..b2eaac23d29 --- /dev/null +++ b/lib/php/test/Unit/Lib/StringFunc/CoreTest.php @@ -0,0 +1,215 @@ +assertEquals($expected, $core->substr($str, $start, $length)); + } + + /** + * @dataProvider strlenDataProvider + */ + public function testStrlen( + $expectedLength, + $str + ) { + $core = new Core(); + $this->assertEquals($expectedLength, $core->strlen($str)); + } + + public function substrDataProvider() + { + yield 'Afrikaans' => [ + 'expected' => 'Afrikaans', + 'str' => 'Afrikaans', + ]; + yield 'Alemannisch' => [ + 'expected' => 'Alemannisch', + 'str' => 'Alemannisch', + ]; + yield 'Aragonés' => [ + 'expected' => 'Aragonés', + 'str' => 'Aragonés', + ]; + yield 'العربية' => [ + 'expected' => 'العربية', + 'str' => 'العربية', + ]; + yield 'مصرى' => [ + 'expected' => 'مصرى', + 'str' => 'مصرى', + ]; + yield 'മലയാളം' => [ + 'expected' => 'മലയാളം', + 'str' => 'മലയാളം', + ]; + yield 'Slovenščina' => [ + 'expected' => 'Slovenščina', + 'str' => 'Slovenščina', + ]; + yield 'Українська' => [ + 'expected' => 'Українська', + 'str' => 'Українська', + ]; + yield 'اردو' => [ + 'expected' => 'اردو', + 'str' => 'اردو', + ]; + yield '中文' => [ + 'expected' => '中文', + 'str' => '中文', + ]; + yield '粵語' => [ + 'expected' => '粵語', + 'str' => '粵語', + ]; + yield 'Afrikaans_SUB' => [ + 'expected' => 'rikaan', + 'str' => 'Afrikaans', + 'start' => 2, + 'length' => 6, + ]; + yield 'Alemannisch_SUB' => [ + 'expected' => 'emanni', + 'str' => 'Alemannisch', + 'start' => 2, + 'length' => 6, + ]; + yield 'Aragonés_SUB' => [ + 'expected' => 'agoné', + 'str' => 'Aragonés', + 'start' => 2, + 'length' => 6, + ]; + yield 'العربية_SUB' => [ + 'expected' => 'لعر', + 'str' => 'العربية', + 'start' => 2, + 'length' => 6, + ]; + yield 'مصرى_SUB' => [ + 'expected' => 'صرى', + 'str' => 'مصرى', + 'start' => 2, + 'length' => 6, + ]; + yield 'മലയാളം_SUB' => [ + 'expected' => 'ലയ', + 'str' => 'മലയാളം', + 'start' => 3, + 'length' => 6, + ]; + yield 'Slovenščina_SUB' => [ + 'expected' => 'ovenš', + 'str' => 'Slovenščina', + 'start' => 2, + 'length' => 6, + ]; + yield 'Українська_SUB' => [ + 'expected' => 'кра', + 'str' => 'Українська', + 'start' => 2, + 'length' => 6, + ]; + yield 'اردو_SUB' => [ + 'expected' => 'ردو', + 'str' => 'اردو', + 'start' => 2, + 'length' => 6, + ]; + yield '中文_SUB' => [ + 'expected' => '文', + 'str' => '中文', + 'start' => 3, + 'length' => 3, + ]; + yield '粵語_SUB' => [ + 'expected' => '語', + 'str' => '粵語', + 'start' => 3, + 'length' => 3, + ]; + } + + public function strlenDataProvider() + { + yield 'Afrikaans' => [ + 'expectedLength' => 9, + 'str' => 'Afrikaans', + ]; + yield 'Alemannisch' => [ + 'expectedLength' => 11, + 'str' => 'Alemannisch', + ]; + yield 'Aragonés' => [ + 'expectedLength' => 9, + 'str' => 'Aragonés', + ]; + yield 'العربية' => [ + 'expectedLength' => 14, + 'str' => 'العربية', + ]; + yield 'مصرى' => [ + 'expectedLength' => 8, + 'str' => 'مصرى', + ]; + yield 'മലയാളം' => [ + 'expectedLength' => 18, + 'str' => 'മലയാളം', + ]; + yield 'Slovenščina' => [ + 'expectedLength' => 13, + 'str' => 'Slovenščina', + ]; + yield 'Українська' => [ + 'expectedLength' => 20, + 'str' => 'Українська', + ]; + yield 'اردو' => [ + 'expectedLength' => 8, + 'str' => 'اردو', + ]; + yield '中文' => [ + 'expectedLength' => 6, + 'str' => '中文', + ]; + yield '粵語' => [ + 'expectedLength' => 6, + 'str' => '粵語', + ]; + } +} diff --git a/lib/php/test/Unit/Lib/StringFunc/MbStringTest.php b/lib/php/test/Unit/Lib/StringFunc/MbStringTest.php new file mode 100644 index 00000000000..5670219955e --- /dev/null +++ b/lib/php/test/Unit/Lib/StringFunc/MbStringTest.php @@ -0,0 +1,215 @@ +assertEquals($expected, $core->substr($str, $start, $length)); + } + + /** + * @dataProvider strlenDataProvider + */ + public function testStrlen( + $expectedLength, + $str + ) { + $core = new Mbstring(); + $this->assertEquals($expectedLength, $core->strlen($str)); + } + + public function substrDataProvider() + { + yield 'Afrikaans' => [ + 'expected' => 'Afrikaans', + 'str' => 'Afrikaans', + ]; + yield 'Alemannisch' => [ + 'expected' => 'Alemannisch', + 'str' => 'Alemannisch', + ]; + yield 'Aragonés' => [ + 'expected' => 'Aragonés', + 'str' => 'Aragonés', + ]; + yield 'العربية' => [ + 'expected' => 'العربية', + 'str' => 'العربية', + ]; + yield 'مصرى' => [ + 'expected' => 'مصرى', + 'str' => 'مصرى', + ]; + yield 'മലയാളം' => [ + 'expected' => 'മലയാളം', + 'str' => 'മലയാളം', + ]; + yield 'Slovenščina' => [ + 'expected' => 'Slovenščina', + 'str' => 'Slovenščina', + ]; + yield 'Українська' => [ + 'expected' => 'Українська', + 'str' => 'Українська', + ]; + yield 'اردو' => [ + 'expected' => 'اردو', + 'str' => 'اردو', + ]; + yield '中文' => [ + 'expected' => '中文', + 'str' => '中文', + ]; + yield '粵語' => [ + 'expected' => '粵語', + 'str' => '粵語', + ]; + yield 'Afrikaans_SUB' => [ + 'expected' => 'rikaan', + 'str' => 'Afrikaans', + 'start' => 2, + 'length' => 6, + ]; + yield 'Alemannisch_SUB' => [ + 'expected' => 'emanni', + 'str' => 'Alemannisch', + 'start' => 2, + 'length' => 6, + ]; + yield 'Aragonés_SUB' => [ + 'expected' => 'agoné', + 'str' => 'Aragonés', + 'start' => 2, + 'length' => 6, + ]; + yield 'العربية_SUB' => [ + 'expected' => 'لعر', + 'str' => 'العربية', + 'start' => 2, + 'length' => 6, + ]; + yield 'مصرى_SUB' => [ + 'expected' => 'صرى', + 'str' => 'مصرى', + 'start' => 2, + 'length' => 6, + ]; + yield 'മലയാളം_SUB' => [ + 'expected' => 'ലയ', + 'str' => 'മലയാളം', + 'start' => 3, + 'length' => 6, + ]; + yield 'Slovenščina_SUB' => [ + 'expected' => 'ovenš', + 'str' => 'Slovenščina', + 'start' => 2, + 'length' => 6, + ]; + yield 'Українська_SUB' => [ + 'expected' => 'кра', + 'str' => 'Українська', + 'start' => 2, + 'length' => 6, + ]; + yield 'اردو_SUB' => [ + 'expected' => 'ردو', + 'str' => 'اردو', + 'start' => 2, + 'length' => 6, + ]; + yield '中文_SUB' => [ + 'expected' => '文', + 'str' => '中文', + 'start' => 3, + 'length' => 3, + ]; + yield '粵語_SUB' => [ + 'expected' => '語', + 'str' => '粵語', + 'start' => 3, + 'length' => 3, + ]; + } + + public function strlenDataProvider() + { + yield 'Afrikaans' => [ + 'expectedLength' => 9, + 'str' => 'Afrikaans', + ]; + yield 'Alemannisch' => [ + 'expectedLength' => 11, + 'str' => 'Alemannisch', + ]; + yield 'Aragonés' => [ + 'expectedLength' => 9, + 'str' => 'Aragonés', + ]; + yield 'العربية' => [ + 'expectedLength' => 14, + 'str' => 'العربية', + ]; + yield 'مصرى' => [ + 'expectedLength' => 8, + 'str' => 'مصرى', + ]; + yield 'മലയാളം' => [ + 'expectedLength' => 18, + 'str' => 'മലയാളം', + ]; + yield 'Slovenščina' => [ + 'expectedLength' => 13, + 'str' => 'Slovenščina', + ]; + yield 'Українська' => [ + 'expectedLength' => 20, + 'str' => 'Українська', + ]; + yield 'اردو' => [ + 'expectedLength' => 8, + 'str' => 'اردو', + ]; + yield '中文' => [ + 'expectedLength' => 6, + 'str' => '中文', + ]; + yield '粵語' => [ + 'expectedLength' => 6, + 'str' => '粵語', + ]; + } +} diff --git a/lib/php/test/Unit/Lib/Transport/TBufferedTransportTest.php b/lib/php/test/Unit/Lib/Transport/TBufferedTransportTest.php new file mode 100644 index 00000000000..dd6003a8541 --- /dev/null +++ b/lib/php/test/Unit/Lib/Transport/TBufferedTransportTest.php @@ -0,0 +1,286 @@ +createMock(TTransport::class); + $bufferedTransport = new TBufferedTransport($transport); + + $transport + ->expects($this->once()) + ->method('isOpen') + ->willReturn(true); + + $this->assertTrue($bufferedTransport->isOpen()); + } + + public function testOpen() + { + $transport = $this->createMock(TTransport::class); + $bufferedTransport = new TBufferedTransport($transport); + + $transport + ->expects($this->once()) + ->method('open') + ->willReturn(null); + + $this->assertNull($bufferedTransport->open()); + } + + public function testClose() + { + $transport = $this->createMock(TTransport::class); + $bufferedTransport = new TBufferedTransport($transport); + + $transport + ->expects($this->once()) + ->method('close') + ->willReturn(null); + + $this->assertNull($bufferedTransport->close()); + } + + public function testPutBack() + { + $transport = $this->createMock(TTransport::class); + $bufferedTransport = new TBufferedTransport($transport); + $bufferedTransport->putBack('test'); + + $ref = new \ReflectionClass($bufferedTransport); + $property = $ref->getProperty('rBuf_'); + $property->setAccessible(true); + $this->assertEquals('test', $property->getValue($bufferedTransport)); + + $bufferedTransport->putBack('abcde'); + $this->assertEquals('abcdetest', $property->getValue($bufferedTransport)); + } + + /** + * @dataProvider readAllDataProvider + */ + public function testReadAll( + $startBuffer, + $readLength, + $bufferReadLength, + $bufferReadResult, + $expectedBufferValue, + $expectedRead + ) { + $transport = $this->createMock(TTransport::class); + $bufferedTransport = new TBufferedTransport($transport); + $bufferedTransport->putBack($startBuffer); + + $transport + ->expects($bufferReadLength > 0 ? $this->once() : $this->never()) + ->method('readAll') + ->with($bufferReadLength) + ->willReturn($bufferReadResult); + + $this->assertEquals($expectedRead, $bufferedTransport->readAll($readLength)); + + $ref = new \ReflectionClass($bufferedTransport); + $property = $ref->getProperty('rBuf_'); + $property->setAccessible(true); + $this->assertEquals($expectedBufferValue, $property->getValue($bufferedTransport)); + } + + public function readAllDataProvider() + { + yield 'buffer empty' => [ + 'startBuffer' => '', + 'readLength' => 5, + 'bufferReadLength' => 5, + 'bufferReadResult' => '12345', + 'expectedBufferValue' => '', + 'expectedRead' => '12345', + ]; + yield 'buffer have partly loaded data' => [ + 'startBuffer' => '12345', + 'readLength' => 10, + 'bufferReadLength' => 5, + 'bufferReadResult' => '67890', + 'expectedBufferValue' => '', + 'expectedRead' => '1234567890', + ]; + yield 'buffer fully read' => [ + 'startBuffer' => '12345', + 'readLength' => 5, + 'bufferReadLength' => 0, + 'bufferReadResult' => '', + 'expectedBufferValue' => '', + 'expectedRead' => '12345', + ]; + yield 'request less data that we have in buffer' => [ + 'startBuffer' => '12345', + 'readLength' => 3, + 'bufferReadLength' => 0, + 'bufferReadResult' => '', + 'expectedBufferValue' => '45', + 'expectedRead' => '123', + ]; + } + + /** + * @dataProvider readDataProvider + */ + public function testRead( + $readBufferSize, + $startBuffer, + $readLength, + $bufferReadResult, + $expectedBufferValue, + $expectedRead + ) { + $transport = $this->createMock(TTransport::class); + $bufferedTransport = new TBufferedTransport($transport, $readBufferSize); + $bufferedTransport->putBack($startBuffer); + + $transport + ->expects(empty($startBuffer) > 0 ? $this->once() : $this->never()) + ->method('read') + ->with($readBufferSize) + ->willReturn($bufferReadResult); + + $this->assertEquals($expectedRead, $bufferedTransport->read($readLength)); + + $ref = new \ReflectionClass($bufferedTransport); + $property = $ref->getProperty('rBuf_'); + $property->setAccessible(true); + $this->assertEquals($expectedBufferValue, $property->getValue($bufferedTransport)); + } + + public function readDataProvider() + { + yield 'buffer empty' => [ + 'readBufferSize' => 10, + 'startBuffer' => '', + 'readLength' => 5, + 'bufferReadResult' => '12345', + 'expectedBufferValue' => '', + 'expectedRead' => '12345', + ]; + yield 'buffer read partly' => [ + 'readBufferSize' => 10, + 'startBuffer' => '', + 'readLength' => 5, + 'bufferReadResult' => '1234567890', + 'expectedBufferValue' => '67890', + 'expectedRead' => '12345', + ]; + yield 'buffer fully read' => [ + 'readBufferSize' => 10, + 'startBuffer' => '12345', + 'readLength' => 5, + 'bufferReadResult' => '', + 'expectedBufferValue' => '', + 'expectedRead' => '12345', + ]; + } + + /** + * @dataProvider writeDataProvider + */ + public function testWrite( + $writeBufferSize, + $writeData, + $bufferedTransportCall, + $expectedWriteBufferValue + ) { + $transport = $this->createMock(TTransport::class); + $bufferedTransport = new TBufferedTransport($transport, 512, $writeBufferSize); + + $transport + ->expects($this->exactly($bufferedTransportCall)) + ->method('write') + ->with($writeData) + ->willReturn(null); + + $this->assertNull($bufferedTransport->write($writeData)); + + $ref = new \ReflectionClass($bufferedTransport); + $property = $ref->getProperty('wBuf_'); + $property->setAccessible(true); + $this->assertEquals($expectedWriteBufferValue, $property->getValue($bufferedTransport)); + } + + public function writeDataProvider() + { + yield 'store data in buffer' => [ + 'writeBufferSize' => 10, + 'writeData' => '12345', + 'bufferedTransportCall' => 0, + 'expectedWriteBufferValue' => '12345', + ]; + yield 'send data to buffered transport' => [ + 'writeBufferSize' => 10, + 'writeData' => '12345678901', + 'bufferedTransportCall' => 1, + 'expectedWriteBufferValue' => '', + ]; + } + + /** + * @dataProvider flushDataProvider + */ + public function testFlush( + $writeBuffer + ) { + $transport = $this->createMock(TTransport::class); + $bufferedTransport = new TBufferedTransport($transport, 512, 512); + $ref = new \ReflectionClass($bufferedTransport); + $property = $ref->getProperty('wBuf_'); + $property->setAccessible(true); + $property->setValue($bufferedTransport, $writeBuffer); + + $transport + ->expects(!empty($writeBuffer) ? $this->once() : $this->never()) + ->method('write') + ->with($writeBuffer) + ->willReturn(null); + + $transport + ->expects($this->once()) + ->method('flush') + ->willReturn(null); + + $this->assertNull($bufferedTransport->flush()); + + $this->assertEquals('', $property->getValue($bufferedTransport)); + } + + public function flushDataProvider() + { + yield 'empty buffer' => [ + 'writeBuffer' => '', + ]; + yield 'not empty buffer' => [ + 'writeBuffer' => '12345', + ]; + } +} diff --git a/lib/php/test/Unit/Lib/Transport/TCurlClientTest.php b/lib/php/test/Unit/Lib/Transport/TCurlClientTest.php new file mode 100644 index 00000000000..7cd7446bb42 --- /dev/null +++ b/lib/php/test/Unit/Lib/Transport/TCurlClientTest.php @@ -0,0 +1,423 @@ +setTimeoutSecs(1000); + + $ref = new \ReflectionClass($transport); + $prop = $ref->getProperty('timeout_'); + $prop->setAccessible(true); + $this->assertEquals(1000, $prop->getValue($transport)); + } + + public function testSetConnectionTimeoutSecs() + { + $host = 'localhost'; + $transport = new TCurlClient($host); + $transport->setConnectionTimeoutSecs(1000); + + $ref = new \ReflectionClass($transport); + $prop = $ref->getProperty('connectionTimeout_'); + $prop->setAccessible(true); + $this->assertEquals(1000, $prop->getValue($transport)); + } + + public function testIsOpen() + { + $host = 'localhost'; + $transport = new TCurlClient($host); + $this->assertTrue($transport->isOpen()); + } + + public function testOpen() + { + $host = 'localhost'; + $transport = new TCurlClient($host); + $this->assertNull($transport->open()); + } + + public function testClose() + { + $host = 'localhost'; + $transport = new TCurlClient($host); + + $ref = new \ReflectionClass($transport); + $propRequest = $ref->getProperty('request_'); + $propRequest->setAccessible(true); + $propRequest->setValue($transport, 'testRequest'); + $propResponse = $ref->getProperty('response_'); + $propResponse->setAccessible(true); + $propResponse->setValue($transport, 'testResponse'); + + $this->assertNull($transport->close()); + $this->assertEmpty($propRequest->getValue($transport)); + $this->assertEmpty($propResponse->getValue($transport)); + } + + public function testRead() + { + $host = 'localhost'; + $transport = new TCurlClient($host); + + $ref = new \ReflectionClass($transport); + $propResponse = $ref->getProperty('response_'); + $propResponse->setAccessible(true); + $propResponse->setValue($transport, '1234567890'); + + $response = $transport->read(5); + $this->assertEquals('12345', $response); + $this->assertEquals('67890', $propResponse->getValue($transport)); + + $response = $transport->read(5); + $this->assertEquals('67890', $response); + # The response does not cleaned after reading full answer, maybe it should be fixed + $this->assertEquals('67890', $propResponse->getValue($transport)); + } + + public function testReadAll() + { + $host = 'localhost'; + $transport = new TCurlClient($host); + + $ref = new \ReflectionClass($transport); + $propResponse = $ref->getProperty('response_'); + $propResponse->setAccessible(true); + $propResponse->setValue($transport, '1234567890'); + + $response = $transport->readAll(5); + $this->assertEquals('12345', $response); + $this->assertEquals('67890', $propResponse->getValue($transport)); + } + + public function testReadAll_THRIFT_4656() + { + $host = 'localhost'; + $transport = new TCurlClient($host); + + $ref = new \ReflectionClass($transport); + $propResponse = $ref->getProperty('response_'); + $propResponse->setAccessible(true); + $propResponse->setValue($transport, ''); + + $this->expectException(TTransportException::class); + $this->expectExceptionMessage('TCurlClient could not read 5 bytes'); + $this->expectExceptionCode(TTransportException::UNKNOWN); + + $transport->readAll(5); + } + + public function testWrite() + { + $host = 'localhost'; + $transport = new TCurlClient($host); + + $ref = new \ReflectionClass($transport); + $propRequest = $ref->getProperty('request_'); + $propRequest->setAccessible(true); + $propRequest->setValue($transport, '1234567890'); + + $transport->write('12345'); + $this->assertEquals('123456789012345', $propRequest->getValue($transport)); + } + + public function testAddHeaders() + { + $host = 'localhost'; + $transport = new TCurlClient($host); + + $ref = new \ReflectionClass($transport); + $propRequest = $ref->getProperty('headers_'); + $propRequest->setAccessible(true); + $propRequest->setValue($transport, ['test' => '1234567890']); + + $transport->addHeaders(['test2' => '12345']); + $this->assertEquals(['test' => '1234567890', 'test2' => '12345'], $propRequest->getValue($transport)); + } + + /** + * @dataProvider flushDataProvider + */ + public function testFlush( + $host, + $port, + $uri, + $scheme, + $headers, + $request, + $timeout, + $connectionTimeout, + $curlSetOptCalls, + $response, + $responseError, + $responseCode, + $expectedException = null, + $expectedMessage = null, + $expectedCode = null + ) { + $this->getFunctionMock('Thrift\\Transport', 'register_shutdown_function') + ->expects($this->once()) + ->with( + $this->callback( + function ($arg) { + return is_array( + $arg + ) && $arg[0] === 'Thrift\\Transport\\TCurlClient' && $arg[1] === 'closeCurlHandle'; + } + ) + ); + $this->getFunctionMock('Thrift\\Transport', 'curl_init') + ->expects($this->once()); + + $this->getFunctionMock('Thrift\\Transport', 'curl_setopt') + ->expects($this->any()) + ->withConsecutive(...$curlSetOptCalls) + ->willReturn(true); + + $this->getFunctionMock('Thrift\\Transport', 'curl_exec') + ->expects($this->once()) + ->with($this->anything()) + ->willReturn($response); + + $this->getFunctionMock('Thrift\\Transport', 'curl_error') + ->expects($this->once()) + ->with($this->anything()) + ->willReturn($responseError); + + $this->getFunctionMock('Thrift\\Transport', 'curl_getinfo') + ->expects($this->once()) + ->with($this->anything(), CURLINFO_HTTP_CODE) + ->willReturn($responseCode); + + if (!is_null($expectedException)) { + $this->expectException($expectedException); + $this->expectExceptionMessage($expectedMessage); + $this->expectExceptionCode($expectedCode); + + $this->getFunctionMock('Thrift\\Transport', 'curl_close') + ->expects($this->once()) + ->with($this->anything()); + } + + $transport = new TCurlClient($host, $port, $uri, $scheme); + if (!empty($headers)) { + $transport->addHeaders($headers); + } + $transport->write($request); + if (!empty($timeout)) { + $transport->setTimeoutSecs($timeout); + } + if (!empty($connectionTimeout)) { + $transport->setConnectionTimeoutSecs($connectionTimeout); + } + + $transport->flush(); + } + + public function flushDataProvider() + { + $request = 'request'; + + $default = [ + 'host' => 'localhost', + 'port' => 80, + 'uri' => '', + 'scheme' => 'http', + 'headers' => [], + 'request' => $request, + 'timeout' => null, + 'connectionTimeout' => null, + 'curlSetOptCalls' => [ + [$this->anything(), CURLOPT_RETURNTRANSFER, true], + [$this->anything(), CURLOPT_USERAGENT, 'PHP/TCurlClient'], + [$this->anything(), CURLOPT_CUSTOMREQUEST, 'POST'], + [$this->anything(), CURLOPT_FOLLOWLOCATION, true], + [$this->anything(), CURLOPT_MAXREDIRS, 1], + [ + $this->anything(), + CURLOPT_HTTPHEADER, + [ + 'Accept: application/x-thrift', + 'Content-Type: application/x-thrift', + 'Content-Length: ' . strlen($request), + ], + ], + [$this->anything(), CURLOPT_POSTFIELDS, $request], + [$this->anything(), CURLOPT_URL, 'http://localhost'], + ], + 'response' => 'response', + 'responseError' => '', + 'responseCode' => 200, + ]; + + yield 'default' => $default; + yield 'additionalHeaders' => array_merge( + $default, + [ + 'headers' => ['test' => '1234567890'], + 'curlSetOptCalls' => [ + [$this->anything(), CURLOPT_RETURNTRANSFER, true], + [$this->anything(), CURLOPT_USERAGENT, 'PHP/TCurlClient'], + [$this->anything(), CURLOPT_CUSTOMREQUEST, 'POST'], + [$this->anything(), CURLOPT_FOLLOWLOCATION, true], + [$this->anything(), CURLOPT_MAXREDIRS, 1], + [ + $this->anything(), + CURLOPT_HTTPHEADER, + [ + 'Accept: application/x-thrift', + 'Content-Type: application/x-thrift', + 'Content-Length: ' . strlen($request), + 'test: 1234567890', + ], + ], + [$this->anything(), CURLOPT_POSTFIELDS, $request], + [$this->anything(), CURLOPT_URL, 'http://localhost'], + ], + ] + ); + yield 'uri' => array_merge( + $default, + [ + 'uri' => 'test1234567890', + 'curlSetOptCalls' => [ + [$this->anything(), CURLOPT_RETURNTRANSFER, true], + [$this->anything(), CURLOPT_USERAGENT, 'PHP/TCurlClient'], + [$this->anything(), CURLOPT_CUSTOMREQUEST, 'POST'], + [$this->anything(), CURLOPT_FOLLOWLOCATION, true], + [$this->anything(), CURLOPT_MAXREDIRS, 1], + [ + $this->anything(), + CURLOPT_HTTPHEADER, + [ + 'Accept: application/x-thrift', + 'Content-Type: application/x-thrift', + 'Content-Length: ' . strlen($request), + ], + ], + [$this->anything(), CURLOPT_POSTFIELDS, $request], + [$this->anything(), CURLOPT_URL, 'http://localhost/test1234567890'], + ], + ] + ); + yield 'timeout' => array_merge( + $default, + [ + 'timeout' => 10, + 'connectionTimeout' => 10, + 'curlSetOptCalls' => [ + [$this->anything(), CURLOPT_RETURNTRANSFER, true], + [$this->anything(), CURLOPT_USERAGENT, 'PHP/TCurlClient'], + [$this->anything(), CURLOPT_CUSTOMREQUEST, 'POST'], + [$this->anything(), CURLOPT_FOLLOWLOCATION, true], + [$this->anything(), CURLOPT_MAXREDIRS, 1], + [ + $this->anything(), + CURLOPT_HTTPHEADER, + [ + 'Accept: application/x-thrift', + 'Content-Type: application/x-thrift', + 'Content-Length: ' . strlen($request), + ], + ], + [$this->anything(), CURLOPT_TIMEOUT, 10], + [$this->anything(), CURLOPT_CONNECTTIMEOUT, 10], + [$this->anything(), CURLOPT_POSTFIELDS, $request], + [$this->anything(), CURLOPT_URL, 'http://localhost'], + ], + ] + ); + yield 'timeout msec' => array_merge( + $default, + [ + 'timeout' => 0.1, + 'connectionTimeout' => 0.1, + 'curlSetOptCalls' => [ + [$this->anything(), CURLOPT_RETURNTRANSFER, true], + [$this->anything(), CURLOPT_USERAGENT, 'PHP/TCurlClient'], + [$this->anything(), CURLOPT_CUSTOMREQUEST, 'POST'], + [$this->anything(), CURLOPT_FOLLOWLOCATION, true], + [$this->anything(), CURLOPT_MAXREDIRS, 1], + [ + $this->anything(), + CURLOPT_HTTPHEADER, + [ + 'Accept: application/x-thrift', + 'Content-Type: application/x-thrift', + 'Content-Length: ' . strlen($request), + ], + ], + [$this->anything(), CURLOPT_TIMEOUT_MS, 100], + [$this->anything(), CURLOPT_CONNECTTIMEOUT_MS, 100], + [$this->anything(), CURLOPT_POSTFIELDS, $request], + [$this->anything(), CURLOPT_URL, 'http://localhost'], + ], + ] + ); + yield 'curl_exec return false' => array_merge( + $default, + [ + 'response' => false, + 'expectedException' => TTransportException::class, + 'expectedMessage' => 'TCurlClient: Could not connect to http://localhost', + 'expectedCode' => TTransportException::UNKNOWN, + ] + ); + yield 'curl_exec return response code 403' => array_merge( + $default, + [ + 'responseError' => 'Access denied', + 'responseCode' => 403, + 'expectedException' => TTransportException::class, + 'expectedMessage' => 'TCurlClient: Could not connect to http://localhost, Access denied, HTTP status code: 403', + 'expectedCode' => TTransportException::UNKNOWN, + ] + ); + } + + public function testCloseCurlHandle() + { + $this->getFunctionMock('Thrift\\Transport', 'curl_close') + ->expects($this->once()) + ->with('testHandle'); + + $transport = new TCurlClient('localhost'); + $ref = new \ReflectionClass($transport); + $prop = $ref->getProperty('curlHandle'); + $prop->setAccessible(true); + $prop->setValue($transport, 'testHandle'); + + $transport::closeCurlHandle(); + } +} diff --git a/lib/php/test/Unit/Lib/Transport/TFramedTransportTest.php b/lib/php/test/Unit/Lib/Transport/TFramedTransportTest.php new file mode 100644 index 00000000000..2607ddbf8b6 --- /dev/null +++ b/lib/php/test/Unit/Lib/Transport/TFramedTransportTest.php @@ -0,0 +1,240 @@ +createMock(TTransport::class); + $framedTransport = new TFramedTransport($transport); + + $transport + ->expects($this->once()) + ->method('isOpen') + ->willReturn(true); + + $this->assertTrue($framedTransport->isOpen()); + } + + public function testOpen() + { + $transport = $this->createMock(TTransport::class); + $framedTransport = new TFramedTransport($transport); + + $transport + ->expects($this->once()) + ->method('open') + ->willReturn(null); + + $this->assertNull($framedTransport->open()); + } + + public function testClose() + { + $transport = $this->createMock(TTransport::class); + $framedTransport = new TFramedTransport($transport); + + $transport + ->expects($this->once()) + ->method('close') + ->willReturn(null); + + $this->assertNull($framedTransport->close()); + } + + public function testPutBack() + { + $transport = $this->createMock(TTransport::class); + $framedTransport = new TFramedTransport($transport); + $framedTransport->putBack('test'); + + $ref = new \ReflectionClass($framedTransport); + $property = $ref->getProperty('rBuf_'); + $property->setAccessible(true); + $this->assertEquals('test', $property->getValue($framedTransport)); + + $framedTransport->putBack('abcde'); + $this->assertEquals('abcdetest', $property->getValue($framedTransport)); + } + + /** + * @dataProvider readDataProvider + */ + public function testRead( + $readAllowed, + $readBuffer, + $lowLevelTransportReadResult, + $lowLevelTransportReadAllParams, + $lowLevelTransportReadAllResult, + $readLength, + $expectedReadResult + ) { + $transport = $this->createMock(TTransport::class); + $framedTransport = new TFramedTransport($transport, $readAllowed); + $framedTransport->putBack($readBuffer); + + $transport + ->expects($readAllowed ? $this->never() : $this->once()) + ->method('read') + ->with($readLength) + ->willReturn($lowLevelTransportReadResult); + + $transport + ->expects($this->exactly(count($lowLevelTransportReadAllParams))) + ->method('readAll') + ->withConsecutive(...$lowLevelTransportReadAllParams) + ->willReturnOnConsecutiveCalls(...$lowLevelTransportReadAllResult); + + $this->assertEquals($expectedReadResult, $framedTransport->read($readLength)); + } + + public function readDataProvider() + { + yield 'read not allowed' => [ + 'readAllowed' => false, + 'readBuffer' => '', + 'lowLevelTransportReadResult' => '12345', + 'lowLevelTransportReadAllParams' => [], + 'lowLevelTransportReadAllResult' => [], + 'readLength' => 5, + 'expectedReadResult' => '12345', + ]; + yield 'read fully buffered item' => [ + 'readAllowed' => true, + 'readBuffer' => '', + 'lowLevelTransportReadResult' => '', + 'lowLevelTransportReadAllParams' => [[4], [5]], + 'lowLevelTransportReadAllResult' => [pack('N', '5'), '12345'], + 'readLength' => 5, + 'expectedReadResult' => '12345', + ]; + yield 'read partly buffered item' => [ + 'readAllowed' => true, + 'readBuffer' => '', + 'lowLevelTransportReadResult' => '', + 'lowLevelTransportReadAllParams' => [[4], [10]], + 'lowLevelTransportReadAllResult' => [pack('N', '10'), '1234567890'], + 'readLength' => 5, + 'expectedReadResult' => '12345', + ]; + } + + /** + * @dataProvider writeDataProvider + */ + public function testWrite( + $writeAllowed, + $writeData, + $writeLength, + $expectedWriteBufferValue + ) { + $transport = $this->createMock(TTransport::class); + $framedTransport = new TFramedTransport($transport, true, $writeAllowed); + + $transport + ->expects($writeAllowed ? $this->never() : $this->once()) + ->method('write') + ->with('12345', 5) + ->willReturn(5); + + $framedTransport->write($writeData, $writeLength); + + $ref = new \ReflectionClass($framedTransport); + $property = $ref->getProperty('wBuf_'); + $property->setAccessible(true); + $this->assertEquals($expectedWriteBufferValue, $property->getValue($framedTransport)); + } + + public function writeDataProvider() + { + yield 'write not allowed' => [ + 'writeAllowed' => false, + 'writeData' => '12345', + 'writeLength' => 5, + 'expectedWriteBufferValue' => '', + ]; + yield 'write full' => [ + 'writeAllowed' => true, + 'writeData' => '12345', + 'writeLength' => 5, + 'expectedWriteBufferValue' => '12345', + ]; + yield 'write partly' => [ + 'writeAllowed' => true, + 'writeData' => '1234567890', + 'writeLength' => 5, + 'expectedWriteBufferValue' => '12345', + ]; + } + + /** + * @dataProvider flushDataProvider + */ + public function testFlush( + $writeAllowed, + $writeBuffer, + $lowLevelTransportWrite + ) { + $transport = $this->createMock(TTransport::class); + $framedTransport = new TFramedTransport($transport, true, $writeAllowed); + $ref = new \ReflectionClass($framedTransport); + $property = $ref->getProperty('wBuf_'); + $property->setAccessible(true); + $property->setValue($framedTransport, $writeBuffer); + + $transport + ->expects($this->once()) + ->method('flush'); + + $transport + ->expects($writeAllowed && !empty($writeBuffer) ? $this->once() : $this->never()) + ->method('write') + ->with($lowLevelTransportWrite) + ->willReturn(null); + + $this->assertNull($framedTransport->flush()); + } + + public function flushDataProvider() + { + yield 'write not allowed' => [ + 'writeAllowed' => false, + 'writeBuffer' => '12345', + 'lowLevelTransportWrite' => '', + ]; + yield 'empty buffer' => [ + 'writeAllowed' => true, + 'writeBuffer' => '', + 'lowLevelTransportWrite' => '', + ]; + yield 'write full' => [ + 'writeAllowed' => true, + 'writeBuffer' => '12345', + 'lowLevelTransportWrite' => pack('N', strlen('12345')) . '12345', + ]; + } +} diff --git a/lib/php/test/Unit/Lib/Transport/THttpClientTest.php b/lib/php/test/Unit/Lib/Transport/THttpClientTest.php new file mode 100644 index 00000000000..ce6813c1bd1 --- /dev/null +++ b/lib/php/test/Unit/Lib/Transport/THttpClientTest.php @@ -0,0 +1,332 @@ +setTimeoutSecs(1000); + + $ref = new \ReflectionClass($transport); + $prop = $ref->getProperty('timeout_'); + $prop->setAccessible(true); + $this->assertEquals(1000, $prop->getValue($transport)); + } + + public function testIsOpen() + { + $host = 'localhost'; + $transport = new THttpClient($host); + $this->assertTrue($transport->isOpen()); + } + + public function testOpen() + { + $host = 'localhost'; + $transport = new THttpClient($host); + $this->assertNull($transport->open()); + } + + public function testClose() + { + $handle = fopen('php://temp', 'r+'); + $this->getFunctionMock('Thrift\\Transport', 'fclose') + ->expects($this->once()) + ->with($handle) + ->willReturn(true); + + $host = 'localhost'; + $transport = new THttpClient($host); + + $ref = new \ReflectionClass($transport); + $propRequest = $ref->getProperty('handle_'); + $propRequest->setAccessible(true); + $propRequest->setValue($transport, $handle); + + $this->assertNull($transport->close()); + $this->assertNull($propRequest->getValue($transport)); + } + + /** + * @dataProvider readDataProvider + */ + public function testRead( + $readLen, + $freadResult, + $streamGetMetaDataResult, + $expectedResult, + $expectedException, + $expectedExceptionMessage, + $expectedExceptionCode + ) { + $handle = fopen('php://temp', 'r+'); + $this->getFunctionMock('Thrift\\Transport', 'fread') + ->expects($this->once()) + ->with($handle, $readLen) + ->willReturn($freadResult); + + $this->getFunctionMock('Thrift\\Transport', 'stream_get_meta_data') + ->expects(!empty($streamGetMetaDataResult) ? $this->once() : $this->never()) + ->with($handle) + ->willReturn($streamGetMetaDataResult); + + if ($expectedException) { + $this->expectException($expectedException); + $this->expectExceptionMessage($expectedExceptionMessage); + $this->expectExceptionCode($expectedExceptionCode); + } + + $host = 'localhost'; + $transport = new THttpClient($host); + + $ref = new \ReflectionClass($transport); + $propRequest = $ref->getProperty('handle_'); + $propRequest->setAccessible(true); + $propRequest->setValue($transport, $handle); + + $this->assertEquals($expectedResult, $transport->read($readLen)); + } + + public function readDataProvider() + { + yield 'read success' => [ + 'readLen' => 10, + 'freadResult' => '1234567890', + 'streamGetMetaDataResult' => [], + 'expectedResult' => '1234567890', + 'expectedException' => null, + 'expectedExceptionMessage' => null, + 'expectedExceptionCode' => null, + ]; + yield 'read failed' => [ + 'readLen' => 10, + 'freadResult' => false, + 'streamGetMetaDataResult' => [ + 'timed_out' => false, + ], + 'expectedResult' => '', + 'expectedException' => TTransportException::class, + 'expectedExceptionMessage' => 'THttpClient: Could not read 10 bytes from localhost:80', + 'expectedExceptionCode' => TTransportException::UNKNOWN, + ]; + yield 'read timeout' => [ + 'readLen' => 10, + 'freadResult' => '', + 'streamGetMetaDataResult' => [ + 'timed_out' => true, + ], + 'expectedResult' => '', + 'expectedException' => TTransportException::class, + 'expectedExceptionMessage' => 'THttpClient: timed out reading 10 bytes from localhost:80', + 'expectedExceptionCode' => TTransportException::TIMED_OUT, + ]; + } + + public function testWrite() + { + $host = 'localhost'; + $transport = new THttpClient($host); + + $ref = new \ReflectionClass($transport); + $prop = $ref->getProperty('buf_'); + $prop->setAccessible(true); + + $transport->write('1234567890'); + + $this->assertEquals('1234567890', $prop->getValue($transport)); + } + + /** + * @dataProvider flushDataProvider + */ + public function testFlush( + $host, + $port, + $uri, + $scheme, + $context, + $headers, + $timeout, + $streamContextOptions, + $streamContext, + $fopenResult, + $expectedHost, + $expectedUri, + $expectedException, + $expectedExceptionMessage, + $expectedExceptionCode + ) { + $this->getFunctionMock('Thrift\\Transport', 'stream_context_create') + ->expects($this->once()) + ->with($streamContextOptions) + ->willReturn($streamContext); + + $this->getFunctionMock('Thrift\\Transport', 'fopen') + ->expects($this->once()) + ->with( + $scheme . '://' . $expectedHost . $expectedUri, + 'r', + false, + $streamContext + )->willReturn($fopenResult); + + if ($expectedException) { + $this->expectException($expectedException); + $this->expectExceptionMessage($expectedExceptionMessage); + $this->expectExceptionCode($expectedExceptionCode); + } + + $transport = new THttpClient($host, $port, $uri, $scheme, $context); + if (!empty($headers)) { + $transport->addHeaders($headers); + } + if (!empty($timeout)) { + $transport->setTimeoutSecs($timeout); + } + + $this->assertNull($transport->flush()); + } + + public function flushDataProvider() + { + $default = [ + 'host' => 'localhost', + 'port' => '80', + 'uri' => '', + 'scheme' => 'http', + 'context' => [], + 'headers' => [], + 'timeout' => null, + 'streamContextOptions' => [ + 'http' => [ + 'method' => 'POST', + 'header' => "Host: localhost\r\n" . + "Accept: application/x-thrift\r\n" . + "User-Agent: PHP/THttpClient\r\n" . + "Content-Type: application/x-thrift\r\n" . + "Content-Length: 0", + 'content' => '', + 'max_redirects' => 1, + ], + ], + 'streamContext' => fopen('php://temp', 'r+'), + 'fopenResult' => fopen('php://memory', 'r+'), + 'expectedHost' => 'localhost', + 'expectedUri' => '', + 'expectedException' => '', + 'expectedExceptionMessage' => '', + 'expectedExceptionCode' => '', + ]; + + yield 'success' => $default; + yield 'additionalHeaders' => array_merge( + $default, + [ + 'headers' => [ + 'X-Test-Header' => 'test', + ], + 'streamContextOptions' => [ + 'http' => [ + 'method' => 'POST', + 'header' => "Host: localhost\r\n" . + "Accept: application/x-thrift\r\n" . + "User-Agent: PHP/THttpClient\r\n" . + "Content-Type: application/x-thrift\r\n" . + "Content-Length: 0\r\n" . + "X-Test-Header: test", + 'content' => '', + 'max_redirects' => 1, + ], + ], + ] + ); + yield 'timeout' => array_merge( + $default, + [ + 'timeout' => 1000, + 'streamContextOptions' => [ + 'http' => [ + 'method' => 'POST', + 'header' => "Host: localhost\r\n" . + "Accept: application/x-thrift\r\n" . + "User-Agent: PHP/THttpClient\r\n" . + "Content-Type: application/x-thrift\r\n" . + "Content-Length: 0", + 'content' => '', + 'max_redirects' => 1, + 'timeout' => 1000, + ], + ], + ] + ); + yield 'fopenFailed' => array_merge( + $default, + [ + 'host' => 'localhost', + 'port' => 8080, + 'uri' => 'test', + 'expectedHost' => 'localhost:8080', + 'expectedUri' => '/test', + 'streamContextOptions' => [ + 'http' => [ + 'method' => 'POST', + 'header' => "Host: localhost:8080\r\n" . + "Accept: application/x-thrift\r\n" . + "User-Agent: PHP/THttpClient\r\n" . + "Content-Type: application/x-thrift\r\n" . + "Content-Length: 0", + 'content' => '', + 'max_redirects' => 1, + ], + ], + 'fopenResult' => false, + 'expectedException' => TTransportException::class, + 'expectedExceptionMessage' => 'THttpClient: Could not connect to localhost:8080/test', + 'expectedExceptionCode' => TTransportException::NOT_OPEN, + ] + ); + } + + public function testAddHeaders() + { + $host = 'localhost'; + $transport = new THttpClient($host); + + $ref = new \ReflectionClass($transport); + $propRequest = $ref->getProperty('headers_'); + $propRequest->setAccessible(true); + $propRequest->setValue($transport, ['test' => '1234567890']); + + $transport->addHeaders(['test2' => '12345']); + $this->assertEquals(['test' => '1234567890', 'test2' => '12345'], $propRequest->getValue($transport)); + } +} diff --git a/lib/php/test/Unit/Lib/Transport/TMemoryBufferTest.php b/lib/php/test/Unit/Lib/Transport/TMemoryBufferTest.php new file mode 100644 index 00000000000..06f0012ede5 --- /dev/null +++ b/lib/php/test/Unit/Lib/Transport/TMemoryBufferTest.php @@ -0,0 +1,143 @@ +assertTrue($transport->isOpen()); + } + + public function testOpen() + { + $transport = new TMemoryBuffer(); + $this->assertNull($transport->open()); + } + + public function testClose() + { + $transport = new TMemoryBuffer(); + $this->assertNull($transport->close()); + } + + public function testReadEmptyBuffer() + { + $transport = new TMemoryBuffer(); + $this->expectException(\Thrift\Exception\TTransportException::class); + $this->expectExceptionMessage("TMemoryBuffer: Could not read 1 bytes from buffer."); + $this->expectExceptionCode(TTransportException::UNKNOWN); + $transport->read(1); + } + + /** + * @dataProvider readDataProvider + */ + public function testRead( + $startBuffer, + $readLength, + $expectedRead, + $expectedBuffer + ) { + $transport = new TMemoryBuffer($startBuffer); + $this->assertEquals($expectedRead, $transport->read($readLength)); + $this->assertEquals($expectedBuffer, $transport->getBuffer()); + } + + public function readDataProvider() + { + yield 'Read part of buffer' => [ + 'startBuffer' => '1234567890', + 'readLength' => 5, + 'expectedRead' => '12345', + 'expectedBuffer' => '67890', + ]; + yield 'Read part of buffer UTF' => [ + 'startBuffer' => 'Slovenščina', + 'readLength' => 6, + 'expectedRead' => 'Sloven', + 'expectedBuffer' => 'ščina', + ]; + yield 'Read part of buffer UTF 2' => [ + 'startBuffer' => 'Українська', + 'readLength' => 6, + 'expectedRead' => 'Укр', + 'expectedBuffer' => 'аїнська', + ]; + yield 'Read full' => [ + 'startBuffer' => '123456789', + 'readLength' => 10, + 'expectedRead' => '123456789', + 'expectedBuffer' => '', + ]; + } + + /** + * @dataProvider writeDataProvider + */ + public function testWrite( + $startBuffer, + $writeData, + $expectedBuffer + ) { + $transport = new TMemoryBuffer($startBuffer); + $transport->write($writeData); + $this->assertEquals($expectedBuffer, $transport->getBuffer()); + } + + public function writeDataProvider() + { + yield 'empty start buffer' => [ + 'startBuffer' => '', + 'writeData' => '12345', + 'expectedBuffer' => '12345', + ]; + yield 'not empty start buffer' => [ + 'startBuffer' => '67890', + 'writeData' => '12345', + 'expectedBuffer' => '6789012345', + ]; + yield 'not empty start buffer UTF' => [ + 'startBuffer' => 'Slovenščina', + 'writeData' => 'Українська', + 'expectedBuffer' => 'SlovenščinaУкраїнська', + ]; + } + + public function testAvailable() + { + $transport = new TMemoryBuffer('12345'); + $this->assertEquals('5', $transport->available()); + } + + public function testPutBack() + { + $transport = new TMemoryBuffer('12345'); + $transport->putBack('67890'); + $this->assertEquals('6789012345', $transport->getBuffer()); + } +} diff --git a/lib/php/test/Unit/Lib/Transport/TNullTransportTest.php b/lib/php/test/Unit/Lib/Transport/TNullTransportTest.php new file mode 100644 index 00000000000..044c703571c --- /dev/null +++ b/lib/php/test/Unit/Lib/Transport/TNullTransportTest.php @@ -0,0 +1,62 @@ +assertTrue($transport->isOpen()); + } + + public function testOpen() + { + $transport = new TNullTransport(); + $this->assertNull($transport->open()); + } + + public function testClose() + { + $transport = new TNullTransport(); + $this->assertNull($transport->close()); + } + + public function testRead() + { + $transport = new TNullTransport(); + $this->expectException(TTransportException::class); + $this->expectExceptionMessage("Can't read from TNullTransport."); + $this->expectExceptionCode(0); + $transport->read(1); + } + + public function testWrite() + { + $transport = new TNullTransport(); + $this->assertNull($transport->write('test')); + } +} diff --git a/lib/php/test/Unit/Lib/Transport/TPhpStreamTest.php b/lib/php/test/Unit/Lib/Transport/TPhpStreamTest.php new file mode 100644 index 00000000000..c2f950c106b --- /dev/null +++ b/lib/php/test/Unit/Lib/Transport/TPhpStreamTest.php @@ -0,0 +1,296 @@ + $result) { + $fopenResult[$num] = $result ? fopen(...$result) : $result; + } + + $this->getFunctionMock('Thrift\Transport', 'php_sapi_name') + ->expects(!empty($sapiName) ? $this->once() : $this->never()) + ->willReturn($sapiName); + + $this->getFunctionMock('Thrift\Transport', 'fopen') + ->expects($this->exactly(count($fopenResult))) + ->withConsecutive(...$fopenParams) + ->willReturnOnConsecutiveCalls(...$fopenResult); + + if ($expectedException) { + $this->expectException($expectedException); + $this->expectExceptionMessage($expectedExceptionMessage); + $this->expectExceptionCode($expectedExceptionCode); + } + + $transport = new TPhpStream($mode); + $transport->open(); + } + + public function fopenDataProvider() + { + yield 'readCli' => [ + 'mode' => TPhpStream::MODE_R, + 'sapiName' => 'cli', + 'fopenParams' => [['php://stdin', 'r']], + 'fopenResult' => [['php://temp', 'r']], + 'expectedException' => null, + 'expectedExceptionMessage' => '', + 'expectedExceptionCode' => 0, + ]; + yield 'readNotCli' => [ + 'mode' => TPhpStream::MODE_R, + 'sapiName' => 'apache', + 'fopenParams' => [['php://input', 'r']], + 'fopenResult' => [['php://temp', 'r']], + 'expectedException' => null, + 'expectedExceptionMessage' => '', + 'expectedExceptionCode' => 0, + ]; + yield 'write' => [ + 'mode' => TPhpStream::MODE_W, + 'sapiName' => '', + 'fopenParams' => [['php://output', 'w']], + 'fopenResult' => [['php://temp', 'w']], + 'expectedException' => null, + 'expectedExceptionMessage' => '', + 'expectedExceptionCode' => 0, + ]; + yield 'read and write' => [ + 'mode' => TPhpStream::MODE_R | TPhpStream::MODE_W, + 'sapiName' => 'cli', + 'fopenParams' => [['php://stdin', 'r'], ['php://output', 'w']], + 'fopenResult' => [['php://temp', 'r'], ['php://temp', 'w']], + 'expectedException' => null, + 'expectedExceptionMessage' => '', + 'expectedExceptionCode' => 0, + ]; + yield 'read exception' => [ + 'mode' => TPhpStream::MODE_R, + 'sapiName' => 'cli', + 'fopenParams' => [['php://stdin', 'r']], + 'fopenResult' => [false], + 'expectedException' => TException::class, + 'expectedExceptionMessage' => 'TPhpStream: Could not open php://input', + #should depend on php_sapi_name result + 'expectedExceptionCode' => 0, + ]; + yield 'write exception' => [ + 'mode' => TPhpStream::MODE_W, + 'sapiName' => '', + 'fopenParams' => [['php://output', 'w']], + 'fopenResult' => [false], + 'expectedException' => TException::class, + 'expectedExceptionMessage' => 'TPhpStream: Could not open php://output', + 'expectedExceptionCode' => 0, + ]; + } + + /** + * @dataProvider closeDataProvider + */ + public function testClose( + $mode, + $fopenParams, + $fopenResult + ) { + #due to the running tests in separate process we could not open stream in data provider, so we need to do it here + foreach ($fopenResult as $num => $result) { + $fopenResult[$num] = $result ? fopen(...$result) : $result; + } + + $this->getFunctionMock('Thrift\Transport', 'fopen') + ->expects($this->exactly(count($fopenParams))) + ->withConsecutive(...$fopenParams) + ->willReturnOnConsecutiveCalls(...$fopenResult); + + $this->getFunctionMock('Thrift\Transport', 'fclose') + ->expects($this->exactly(count($fopenParams))) + ->with( + $this->callback(function ($stream) { + return is_resource($stream); + }) + ) + ->willReturn(true); + + $transport = new TPhpStream($mode); + $transport->open(); + $this->assertTrue($transport->isOpen()); + + $transport->close(); + $this->assertFalse($transport->isOpen()); + } + + public function closeDataProvider() + { + $read = ['php://temp', 'r']; + $write = ['php://temp', 'w']; + yield 'read' => [ + 'mode' => TPhpStream::MODE_R, + 'fopenParams' => [['php://stdin', 'r']], + 'fopenResult' => [$read], + ]; + yield 'write' => [ + 'mode' => TPhpStream::MODE_W, + 'fopenParams' => [['php://output', 'w']], + 'fopenResult' => [$write], + ]; + yield 'read and write' => [ + 'mode' => TPhpStream::MODE_R | TPhpStream::MODE_W, + 'fopenParams' => [['php://stdin', 'r'], ['php://output', 'w']], + 'fopenResult' => [$read, $write], + ]; + } + + /** + * @dataProvider readDataProvider + */ + public function testRead( + $freadResult, + $expectedResult, + $expectedException, + $expectedExceptionMessage, + $expectedExceptionCode + ) { + $this->getFunctionMock('Thrift\Transport', 'fread') + ->expects($this->once()) + ->with($this->anything(), 5) + ->willReturn($freadResult); + + if ($expectedException) { + $this->expectException($expectedException); + $this->expectExceptionMessage($expectedExceptionMessage); + $this->expectExceptionCode($expectedExceptionCode); + } + + $transport = new TPhpStream(TPhpStream::MODE_R); + $this->assertEquals($expectedResult, $transport->read(5)); + } + + public function readDataProvider() + { + yield 'success' => [ + 'freadResult' => '12345', + 'expectedResult' => '12345', + 'expectedException' => null, + 'expectedExceptionMessage' => '', + 'expectedExceptionCode' => 0, + ]; + yield 'empty' => [ + 'freadResult' => '', + 'expectedResult' => '', + 'expectedException' => TException::class, + 'expectedExceptionMessage' => 'TPhpStream: Could not read 5 bytes', + 'expectedExceptionCode' => 0, + ]; + yield 'false' => [ + 'freadResult' => false, + 'expectedResult' => false, + 'expectedException' => TException::class, + 'expectedExceptionMessage' => 'TPhpStream: Could not read 5 bytes', + 'expectedExceptionCode' => 0, + ]; + } + + /** + * @dataProvider writeDataProvider + */ + public function testWrite( + $buf, + $fwriteParams, + $fwriteResult, + $expectedException, + $expectedExceptionMessage, + $expectedExceptionCode + ) { + $this->getFunctionMock('Thrift\Transport', 'fwrite') + ->expects($this->exactly(count($fwriteParams))) + ->withConsecutive(...$fwriteParams) + ->willReturnOnConsecutiveCalls(...$fwriteResult); + + if ($expectedException) { + $this->expectException($expectedException); + $this->expectExceptionMessage($expectedExceptionMessage); + $this->expectExceptionCode($expectedExceptionCode); + } + + $transport = new TPhpStream(TPhpStream::MODE_W); + $transport->write($buf); + } + + public function writeDataProvider() + { + yield 'success' => [ + 'buf' => '12345', + 'fwriteParams' => [[$this->anything(), '12345']], + 'fwriteResult' => [5], + 'expectedException' => null, + 'expectedExceptionMessage' => '', + 'expectedExceptionCode' => 0, + ]; + yield 'several iteration' => [ + 'buf' => '1234567890', + 'fwriteParams' => [[$this->anything(), '1234567890'], [$this->anything(), '67890']], + 'fwriteResult' => [5, 5], + 'expectedException' => null, + 'expectedExceptionMessage' => '', + 'expectedExceptionCode' => 0, + ]; + yield 'fail' => [ + 'buf' => '1234567890', + 'fwriteParams' => [[$this->anything(), '1234567890']], + 'fwriteResult' => [false], + 'expectedException' => TException::class, + 'expectedExceptionMessage' => 'TPhpStream: Could not write 10 bytes', + 'expectedExceptionCode' => 0, + ]; + } + + public function testFlush() + { + $this->getFunctionMock('Thrift\Transport', 'fflush') + ->expects($this->once()); + + $transport = new TPhpStream(TPhpStream::MODE_R); + $transport->flush(); + } +} diff --git a/lib/php/test/Unit/Lib/Transport/TSSLSocketTest.php b/lib/php/test/Unit/Lib/Transport/TSSLSocketTest.php new file mode 100644 index 00000000000..71772190bce --- /dev/null +++ b/lib/php/test/Unit/Lib/Transport/TSSLSocketTest.php @@ -0,0 +1,247 @@ +expectException($expectedException); + $this->expectExceptionMessage($expectedMessage); + $this->expectExceptionCode($expectedCode); + + $this->getFunctionMock('Thrift\Transport', 'stream_socket_client') + ->expects($this->exactly($streamSocketClientCallCount)) + ->with( + 'ssl://' . $host . ':' . $port, + $this->anything(), #$errno, + $this->anything(), #$errstr, + $this->anything(), #$this->sendTimeoutSec_ + ($this->sendTimeoutUsec_ / 1000000), + STREAM_CLIENT_CONNECT, + $this->anything() #$context + ) + ->willReturn(false); + + $socket = new TSSLSocket( + $host, + $port, + $context, + $debugHandler + ); + $socket->open(); + } + + public function openExceptionDataProvider() + { + yield 'host is empty' => [ + 'host' => '', + 'port' => 9090, + 'context' => null, + 'debugHandler' => null, + 'streamSocketClientCallCount' => 0, + 'expectedException' => TTransportException::class, + 'expectedMessage' => 'Cannot open null host', + 'expectedCode' => TTransportException::NOT_OPEN, + ]; + yield 'port is not positive' => [ + 'host' => 'localhost', + 'port' => 0, + 'context' => null, + 'debugHandler' => null, + 'streamSocketClientCallCount' => 0, + 'expectedException' => TTransportException::class, + 'expectedMessage' => 'Cannot open without port', + 'expectedCode' => TTransportException::NOT_OPEN, + ]; + yield 'connection failure' => [ + 'host' => 'nonexistent-host', + 'port' => 9090, + 'context' => null, + 'debugHandler' => null, + 'streamSocketClientCallCount' => 1, + 'expectedException' => TException::class, + 'expectedMessage' => 'TSocket: Could not connect to', + 'expectedCode' => TTransportException::UNKNOWN, + ]; + } + + public function testDoubleConnect(): void + { + $host = 'localhost'; + $port = 9090; + $context = null; + $debugHandler = null; + + $this->getFunctionMock('Thrift\Transport', 'stream_socket_client') + ->expects($this->once()) + ->with( + 'ssl://' . $host . ':' . $port, + $this->anything(), #$errno, + $this->anything(), #$errstr, + $this->anything(), #$this->sendTimeoutSec_ + ($this->sendTimeoutUsec_ / 1000000), + STREAM_CLIENT_CONNECT, + $this->anything() #$context + ) + ->willReturn(fopen('php://memory', 'r+')); + + $transport = new TSSLSocket( + $host, + $port, + $context, + $debugHandler + ); + + $transport->open(); + $this->expectException(TTransportException::class); + $this->expectExceptionMessage('Socket already connected'); + $this->expectExceptionCode(TTransportException::ALREADY_OPEN); + $transport->open(); + } + + public function testDebugHandler() + { + $host = 'nonexistent-host'; + $port = 9090; + $context = null; + + $debugHandler = function ($error) { + $this->assertEquals( + 'TSocket: Could not connect to ssl://nonexistent-host:9090 (Connection refused [999])', + $error + ); + }; + + $this->getFunctionMock('Thrift\Transport', 'stream_socket_client') + ->expects($this->once()) + ->with( + 'ssl://' . $host . ':' . $port, + $this->anything(), #$errno, + $this->anything(), #$errstr, + $this->anything(), #$this->sendTimeoutSec_ + ($this->sendTimeoutUsec_ / 1000000), + STREAM_CLIENT_CONNECT, + $this->anything() #$context + ) + ->willReturnCallback( + function ($host, &$error_code, &$error_message, $timeout, $flags, $context) { + $error_code = 999; + $error_message = 'Connection refused'; + + return false; + } + ); + + $this->expectException(\Exception::class); + $this->expectExceptionMessage('TSocket: Could not connect to'); + $this->expectExceptionCode(0); + + $transport = new TSSLSocket( + $host, + $port, + $context, + $debugHandler + ); + $transport->setDebug(true); + $transport->open(); + } + + public function testOpenWithContext() + { + $host = 'self-signed-localhost'; + $port = 9090; + $context = stream_context_create( + [ + 'ssl' => [ + 'verify_peer' => true, + 'verify_peer_name' => true, + 'allow_self_signed' => true, + ], + ] + ); + $debugHandler = null; + + $this->getFunctionMock('Thrift\Transport', 'stream_socket_client') + ->expects($this->once()) + ->with( + 'ssl://' . $host . ':' . $port, + $this->anything(), #$errno, + $this->anything(), #$errstr, + $this->anything(), #$this->sendTimeoutSec_ + ($this->sendTimeoutUsec_ / 1000000), + STREAM_CLIENT_CONNECT, + $context #$context + ) + ->willReturn(fopen('php://memory', 'r+')); + + $transport = new TSSLSocket( + $host, + $port, + $context, + $debugHandler + ); + + + $transport->open(); + $this->assertTrue($transport->isOpen()); + } + + /** + * @dataProvider hostDataProvider + */ + public function testGetHost($host, $expected) + { + $port = 9090; + $context = null; + $debugHandler = null; + $transport = new TSSLSocket( + $host, + $port, + $context, + $debugHandler + ); + $this->assertEquals($expected, $transport->getHost()); + } + + public function hostDataProvider() + { + yield 'localhost' => ['localhost', 'ssl://localhost']; + yield 'ssl_localhost' => ['ssl://localhost', 'ssl://localhost']; + yield 'http_localhost' => ['http://localhost', 'http://localhost']; + } +} diff --git a/lib/php/test/Unit/Lib/Transport/TSocketPoolTest.php b/lib/php/test/Unit/Lib/Transport/TSocketPoolTest.php new file mode 100644 index 00000000000..01e45325bc8 --- /dev/null +++ b/lib/php/test/Unit/Lib/Transport/TSocketPoolTest.php @@ -0,0 +1,541 @@ +getProperty('servers_'); + $serversProp->setAccessible(true); + + $this->assertEquals($expectedServers, $serversProp->getValue($socketPool)); + } + + + public function constructDataProvider() + { + yield 'one server' => [ + ['localhost'], + [9090], + false, + null, + [ + ['host' => 'localhost', 'port' => 9090], + ], + ]; + yield 'two servers' => [ + ['localhost1', 'localhost2'], + [9090, 9091], + false, + null, + [ + ['host' => 'localhost1', 'port' => 9090], + ['host' => 'localhost2', 'port' => 9091], + ], + ]; + yield 'one server with one port' => [ + ['localhost'], + 9090, + false, + null, + [ + ['host' => 'localhost', 'port' => 9090], + ], + ]; + yield 'two servers with one port' => [ + ['localhost1', 'localhost2'], + 9090, + false, + null, + [ + ['host' => 'localhost1', 'port' => 9090], + ['host' => 'localhost2', 'port' => 9090], + ], + ]; + } + + public function testAddServer(): void + { + $socketPool = new TSocketPool([], []); + $socketPool->addServer('localhost', 9090); + + $ref = new \ReflectionObject($socketPool); + $servers = $ref->getProperty('servers_'); + $servers->setAccessible(true); + + $this->assertEquals([['host' => 'localhost', 'port' => 9090]], $servers->getValue($socketPool)); + } + + public function testSetNumRetries(): void + { + $socketPool = new TSocketPool([], []); + $socketPool->setNumRetries(5); + + $ref = new \ReflectionObject($socketPool); + $numRetries = $ref->getProperty('numRetries_'); + $numRetries->setAccessible(true); + + $this->assertEquals(5, $numRetries->getValue($socketPool)); + } + + public function testrSetRetryInterval(): void + { + $socketPool = new TSocketPool([], []); + $socketPool->setRetryInterval(5); + + $ref = new \ReflectionObject($socketPool); + $retryInterval = $ref->getProperty('retryInterval_'); + $retryInterval->setAccessible(true); + + $this->assertEquals(5, $retryInterval->getValue($socketPool)); + } + + public function testrSetMaxConsecutiveFailures(): void + { + $socketPool = new TSocketPool([], []); + $socketPool->setMaxConsecutiveFailures(5); + + $ref = new \ReflectionObject($socketPool); + $maxConsecutiveFailures = $ref->getProperty('maxConsecutiveFailures_'); + $maxConsecutiveFailures->setAccessible(true); + + $this->assertEquals(5, $maxConsecutiveFailures->getValue($socketPool)); + } + + public function testrSetRandomize(): void + { + $socketPool = new TSocketPool([], []); + $socketPool->setRandomize(false); + + $ref = new \ReflectionObject($socketPool); + $randomize = $ref->getProperty('randomize_'); + $randomize->setAccessible(true); + + $this->assertEquals(false, $randomize->getValue($socketPool)); + } + + public function testrSetAlwaysTryLast(): void + { + $socketPool = new TSocketPool([], []); + $socketPool->setAlwaysTryLast(false); + + $ref = new \ReflectionObject($socketPool); + $alwaysTryLast = $ref->getProperty('alwaysTryLast_'); + $alwaysTryLast->setAccessible(true); + + $this->assertEquals(false, $alwaysTryLast->getValue($socketPool)); + } + + /** + * @dataProvider openDataProvider + */ + public function testOpen( + $hosts, + $ports, + $persist, + $debugHandler, + $randomize, + $retryInterval, + $numRetries, + $maxConsecutiveFailures, + $debug, + $servers, + $functionExistCallParams, + $functionExistResult, + $apcuFetchCallParams, + $apcuFetchResult, + $timeResult, + $debugHandlerCall, + $apcuStoreCallParams, + $fsockopenCallParams, + $fsockopenResult, + $expectedException, + $expectedExceptionMessage + ) { + $this->getFunctionMock('Thrift\Transport', 'function_exists') + ->expects($this->exactly(count($functionExistCallParams))) + ->withConsecutive(...$functionExistCallParams) + ->willReturnOnConsecutiveCalls(...$functionExistResult); + + $this->getFunctionMock('Thrift\Transport', 'shuffle') + ->expects($randomize ? $this->once() : $this->never()) + ->with($servers) + ->willReturnCallback(function (array &$servers) { + $servers = array_reverse($servers); + + return true; + }); + + $this->getFunctionMock('Thrift\Transport', 'apcu_fetch') + ->expects($this->exactly(count($apcuFetchCallParams))) + ->withConsecutive(...$apcuFetchCallParams) + ->willReturnOnConsecutiveCalls(...$apcuFetchResult); + + $this->getFunctionMock('Thrift\Transport', 'call_user_func') + ->expects($this->exactly(count($debugHandlerCall))) + ->withConsecutive(...$debugHandlerCall) + ->willReturn(true); + + $this->getFunctionMock('Thrift\Transport', 'apcu_store') + ->expects($this->exactly(count($apcuStoreCallParams))) + ->withConsecutive(...$apcuStoreCallParams) + ->willReturn(true); + + $this->getFunctionMock('Thrift\Transport', 'time') + ->expects($this->exactly(count($timeResult))) + ->willReturnOnConsecutiveCalls(...$timeResult); + + #due to the running tests in separate process we could not open stream in data provider, so we need to do it here + foreach ($fsockopenResult as $num => $result) { + $fsockopenResult[$num] = $result ? fopen(...$result) : $result; + } + + $this->getFunctionMock('Thrift\Transport', $persist ? 'pfsockopen' : 'fsockopen') + ->expects($this->exactly(count($fsockopenCallParams))) + ->withConsecutive(...$fsockopenCallParams) + ->willReturnOnConsecutiveCalls(...$fsockopenResult); + + $this->getFunctionMock('Thrift\Transport', 'socket_import_stream') + ->expects(is_null($expectedException) ? $this->once() : $this->never()) + ->with( + $this->callback(function ($stream) { + return is_resource($stream); + }) + ) + ->willReturn(true); + + $this->getFunctionMock('Thrift\Transport', 'socket_set_option') + ->expects(is_null($expectedException) ? $this->once() : $this->never()) + ->with( + $this->anything(), #$socket, + SOL_TCP, #$level + TCP_NODELAY, #$option + 1 #$value + ) + ->willReturn(true); + + if ($expectedException) { + $this->expectException($expectedException); + $this->expectExceptionMessage($expectedExceptionMessage); + } + + $socketPool = new TSocketPool($hosts, $ports, $persist, $debugHandler); + $socketPool->setRandomize($randomize); + $socketPool->setRetryInterval($retryInterval); + $socketPool->setNumRetries($numRetries); + $socketPool->setMaxConsecutiveFailures($maxConsecutiveFailures); + $socketPool->setDebug($debug); + + $this->assertNull($socketPool->open()); + } + + public function openDataProvider() + { + $default = [ + 'hosts' => ['localhost'], + 'ports' => [9090], + 'persist' => false, + 'debugHandler' => null, + 'randomize' => true, + 'retryInterval' => 5, + 'numRetries' => 1, + 'maxConsecutiveFailures' => 1, + 'debug' => false, + 'servers' => [ + ['host' => 'localhost', 'port' => 9090], + ], + 'functionExistCallParams' => [ + ['apcu_fetch'], + ['socket_import_stream'], + ['socket_set_option'], + ], + 'functionExistResult' => [ + true, + true, + true, + ], + 'apcuFetchCallParams' => [ + ['thrift_failtime:localhost:9090~', $this->anything()], + ], + 'apcuFetchResult' => [ + false, + ], + 'timeResult' => [], + 'debugHandlerCall' => [], + 'apcuStoreCallParams' => [], + 'fsockopenCallParams' => [ + [ + 'localhost', + 9090, + $this->anything(), #$errno, + $this->anything(), #$errstr, + $this->anything(), #$this->sendTimeoutSec_ + ($this->sendTimeoutUsec_ / 1000000), + ], + ], + 'fsockopenResult' => [ + ['php://temp', 'r'], + ], + 'expectedException' => null, + 'expectedExceptionMessage' => null, + ]; + + yield 'one server ready' => $default; + yield 'one server failed' => array_merge( + $default, + [ + 'functionExistCallParams' => [ + ['apcu_fetch'], + ], + 'fsockopenResult' => [ + false, + ], + 'apcuFetchCallParams' => [ + ['thrift_failtime:localhost:9090~', $this->anything()], + ['thrift_consecfails:localhost:9090~', $this->anything()], + ], + 'apcuStoreCallParams' => [ + ['thrift_failtime:localhost:9090~', $this->anything()], + ['thrift_consecfails:localhost:9090~', $this->anything(), 0], + ], + 'timeResult' => [ + 1, + ], + 'expectedException' => TException::class, + 'expectedExceptionMessage' => 'TSocketPool: All hosts in pool are down. (localhost:9090)', + ] + ); + yield 'connect to one server on second attempt' => array_merge( + $default, + [ + 'numRetries' => 2, + 'fsockopenCallParams' => [ + [ + 'localhost', + 9090, + $this->anything(), #$errno, + $this->anything(), #$errstr, + $this->anything(), #$this->sendTimeoutSec_ + ($this->sendTimeoutUsec_ / 1000000), + ], + [ + 'localhost', + 9090, + $this->anything(), #$errno, + $this->anything(), #$errstr, + $this->anything(), #$this->sendTimeoutSec_ + ($this->sendTimeoutUsec_ / 1000000), + ], + ], + 'fsockopenResult' => [ + false, + ['php://temp', 'r'], + ], + 'apcuStoreCallParams' => [], + ] + ); + yield 'last time fail time is not expired' => array_merge( + $default, + [ + 'retryInterval' => 5, + 'apcuFetchResult' => [ + 99, + ], + 'apcuStoreCallParams' => [ + ['thrift_failtime:localhost:9090~', $this->anything()], + ], + 'timeResult' => [ + 100, + ], + ] + ); + yield 'last time fail time is expired, store info to debug' => array_merge( + $default, + [ + 'retryInterval' => 5, + 'apcuFetchResult' => [ + 90, + ], + 'apcuStoreCallParams' => [ + ['thrift_failtime:localhost:9090~', $this->anything()], + ], + 'timeResult' => [ + 100, + ], + 'debug' => true, + 'debugHandlerCall' => [ + ['error_log', 'TSocketPool: retryInterval (5) has passed for host localhost:9090'], + ], + ] + ); + yield 'not accessible server, store info to debug' => array_merge( + $default, + [ + 'retryInterval' => 5, + 'functionExistCallParams' => [ + ['apcu_fetch'], + ], + 'functionExistResult' => [ + true, + ], + 'apcuFetchCallParams' => [ + ['thrift_failtime:localhost:9090~', $this->anything()], + ['thrift_consecfails:localhost:9090~', $this->anything()], + ], + 'apcuFetchResult' => [ + 90, + ], + 'apcuStoreCallParams' => [ + ['thrift_failtime:localhost:9090~', $this->anything()], + ['thrift_consecfails:localhost:9090~', 0], + ], + 'timeResult' => [ + 100, + 101, + ], + 'fsockopenResult' => [ + false, + ], + 'debug' => true, + 'debugHandlerCall' => [ + ['error_log', 'TSocketPool: retryInterval (5) has passed for host localhost:9090'], + ['error_log', 'TSocket: Could not connect to localhost:9090 ( [])'], + ['error_log', 'TSocketPool: marking localhost:9090 as down for 5 secs after 1 failed attempts.'], + ['error_log', 'TSocketPool: All hosts in pool are down. (localhost:9090)'], + ], + 'expectedException' => TException::class, + 'expectedExceptionMessage' => 'TSocketPool: All hosts in pool are down. (localhost:9090)', + ] + ); + yield 'max consecutive failures' => array_merge( + $default, + [ + 'maxConsecutiveFailures' => 5, + 'functionExistCallParams' => [ + ['apcu_fetch'], + ], + 'functionExistResult' => [ + true, + ], + 'apcuFetchCallParams' => [ + ['thrift_failtime:localhost:9090~', $this->anything()], + ['thrift_consecfails:localhost:9090~', $this->anything()], + ], + 'apcuStoreCallParams' => [ + ['thrift_consecfails:localhost:9090~', 1], + ], + 'timeResult' => [], + 'fsockopenResult' => [ + false, + ], + 'expectedException' => TException::class, + 'expectedExceptionMessage' => 'TSocketPool: All hosts in pool are down. (localhost:9090)', + ] + ); + yield 'apcu disabled' => array_merge( + $default, + [ + 'functionExistCallParams' => [ + ['apcu_fetch'], + ], + 'functionExistResult' => [ + false, + ], + 'fsockopenResult' => [ + false, + ], + 'timeResult' => [ + 1, + ], + 'apcuFetchCallParams' => [], + 'apcuStoreCallParams' => [], + 'expectedException' => TException::class, + 'expectedExceptionMessage' => 'TSocketPool: All hosts in pool are down. (localhost:9090)', + ] + ); + yield 'second host accessible' => array_merge( + $default, + [ + 'hosts' => ['host1', 'host2'], + 'ports' => [9090, 9091], + 'servers' => [ + ['host' => 'host1', 'port' => 9090], + ['host' => 'host2', 'port' => 9091], + ], + 'fsockopenCallParams' => [ + [ + 'host2', + 9091, + $this->anything(), #$errno, + $this->anything(), #$errstr, + $this->anything(), #$this->sendTimeoutSec_ + ($this->sendTimeoutUsec_ / 1000000), + ], + [ + 'host1', + 9090, + $this->anything(), #$errno, + $this->anything(), #$errstr, + $this->anything(), #$this->sendTimeoutSec_ + ($this->sendTimeoutUsec_ / 1000000), + ], + ], + 'fsockopenResult' => [ + false, + ['php://temp', 'r'], + ], + 'apcuFetchCallParams' => [ + ['thrift_failtime:host2:9091~', $this->anything()], + ['thrift_consecfails:host2:9091~', $this->anything()], + ['thrift_failtime:host1:9090~', $this->anything()], + ], + 'apcuStoreCallParams' => [ + ['thrift_failtime:host2:9091~', $this->anything()], + ['thrift_consecfails:host2:9091~', $this->anything(), 0], + ], + 'timeResult' => [ + 1, + ], + ] + ); + } +} diff --git a/lib/php/test/Unit/Lib/Transport/TSocketTest.php b/lib/php/test/Unit/Lib/Transport/TSocketTest.php new file mode 100644 index 00000000000..a0817a8a587 --- /dev/null +++ b/lib/php/test/Unit/Lib/Transport/TSocketTest.php @@ -0,0 +1,713 @@ +expectException($expectedException); + $this->expectExceptionMessage($expectedMessage); + $this->expectExceptionCode($expectedCode); + + $this->getFunctionMock('Thrift\Transport', 'fsockopen') + ->expects($this->exactly($fsockopenCallCount)) + ->with( + $host, + $port, + $this->anything(), #$errno, + $this->anything(), #$errstr, + $this->anything() #$this->sendTimeoutSec_ + ($this->sendTimeoutUsec_ / 1000000), + ) + ->willReturn(false); + + $socket = new TSocket( + $host, + $port, + $persist, + $debugHandler + ); + $socket->open(); + } + + public function openExceptionDataProvider() + { + yield 'host is empty' => [ + 'host' => '', + 'port' => 9090, + 'persist' => null, + 'debugHandler' => false, + 'fsockopenCallCount' => 0, + 'expectedException' => TTransportException::class, + 'expectedMessage' => 'Cannot open null host', + 'expectedCode' => TTransportException::NOT_OPEN, + ]; + yield 'port is not positive' => [ + 'host' => 'localhost', + 'port' => 0, + 'persist' => false, + 'debugHandler' => null, + 'fsockopenCallCount' => 0, + 'expectedException' => TTransportException::class, + 'expectedMessage' => 'Cannot open without port', + 'expectedCode' => TTransportException::NOT_OPEN, + ]; + yield 'connection failure' => [ + 'host' => 'nonexistent-host', + 'port' => 9090, + 'persist' => false, + 'debugHandler' => null, + 'fsockopenCallCount' => 1, + 'expectedException' => TException::class, + 'expectedMessage' => 'TSocket: Could not connect to', + 'expectedCode' => TTransportException::UNKNOWN, + ]; + } + + public function testDoubleConnect(): void + { + $host = 'localhost'; + $port = 9090; + $persist = false; + $debugHandler = null; + $handle = fopen('php://memory', 'r+'); + $this->getFunctionMock('Thrift\Transport', 'fsockopen') + ->expects($this->once()) + ->with( + $host, + $port, + $this->anything(), #$errno, + $this->anything(), #$errstr, + $this->anything() #$this->sendTimeoutSec_ + ($this->sendTimeoutUsec_ / 1000000), + ) + ->willReturn($handle); + + $this->getFunctionMock('Thrift\Transport', 'socket_import_stream') + ->expects($this->once()) + ->with($handle) + ->willReturn(true); + + $this->getFunctionMock('Thrift\Transport', 'socket_set_option') + ->expects($this->once()) + ->with( + $this->anything(), #$socket, + SOL_TCP, #$level + TCP_NODELAY, #$option + 1 #$value + ) + ->willReturn(true); + + $transport = new TSocket( + $host, + $port, + $persist, + $debugHandler + ); + + $transport->open(); + $this->expectException(TTransportException::class); + $this->expectExceptionMessage('Socket already connected'); + $this->expectExceptionCode(TTransportException::ALREADY_OPEN); + $transport->open(); + } + + public function testDebugHandler() + { + $host = 'nonexistent-host'; + $port = 9090; + $false = false; + + $debugHandler = function ($error) { + $this->assertEquals( + 'TSocket: Could not connect to nonexistent-host:9090 (Connection refused [999])', + $error + ); + }; + + $this->getFunctionMock('Thrift\Transport', 'fsockopen') + ->expects($this->once()) + ->with( + $host, + $port, + $this->anything(), #$errno, + $this->anything(), #$errstr, + $this->anything() #$this->sendTimeoutSec_ + ($this->sendTimeoutUsec_ / 1000000), + ) + ->willReturnCallback( + function ( + string $hostname, + int $port, + &$error_code, + &$error_message, + ?float $timeout + ) { + $error_code = 999; + $error_message = 'Connection refused'; + + return false; + } + ); + + $transport = new TSocket( + $host, + $port, + $false, + $debugHandler + ); + $transport->setDebug(true); + + $this->expectException(\Exception::class); + $this->expectExceptionMessage('TSocket: Could not connect to'); + $this->expectExceptionCode(0); + $transport->open(); + } + + public function testOpenPersist() + { + $host = 'persist-localhost'; + $port = 9090; + $persist = true; + $debugHandler = null; + + $handle = fopen('php://memory', 'r+'); + + $this->getFunctionMock('Thrift\Transport', 'pfsockopen') + ->expects($this->once()) + ->with( + $host, + $port, + $this->anything(), #$errno, + $this->anything(), #$errstr, + $this->anything() #$this->sendTimeoutSec_ + ($this->sendTimeoutUsec_ / 1000000), + ) + ->willReturn($handle); + + $this->getFunctionMock('Thrift\Transport', 'socket_import_stream') + ->expects($this->once()) + ->with($handle) + ->willReturn(true); + + $this->getFunctionMock('Thrift\Transport', 'socket_set_option') + ->expects($this->once()) + ->with( + $this->anything(), #$socket, + SOL_TCP, #$level + TCP_NODELAY, #$option + 1 #$value + ) + ->willReturn(true); + + $transport = new TSocket( + $host, + $port, + $persist, + $debugHandler + ); + + $transport->open(); + $this->assertTrue($transport->isOpen()); + } + + public function testOpenUnixSocket() + { + $host = 'unix:///tmp/ipc.sock'; + $port = -1; + $persist = false; + $debugHandler = null; + $handle = fopen('php://memory', 'r+'); + + $this->getFunctionMock('Thrift\Transport', 'fsockopen') + ->expects($this->once()) + ->with( + $host, + $port, + $this->anything(), #$errno, + $this->anything(), #$errstr, + $this->anything() #$this->sendTimeoutSec_ + ($this->sendTimeoutUsec_ / 1000000), + ) + ->willReturn($handle); + + $this->getFunctionMock('Thrift\Transport', 'socket_import_stream') + ->expects($this->once()) + ->with($handle) + ->willReturn(true); + + $this->getFunctionMock('Thrift\Transport', 'socket_set_option') + ->expects($this->once()) + ->with( + $this->anything(), #$socket, + SOL_TCP, #$level + TCP_NODELAY, #$option + 1 #$value + ) + ->willReturn(true); + + $transport = new TSocket( + $host, + $port, + $persist, + $debugHandler + ); + + $transport->open(); + } + + /** + * @dataProvider open_THRIFT_5132_DataProvider + */ + public function testOpen_THRIFT_5132( + $socketImportResult + ) { + $host = 'localhost'; + $port = 9090; + $persist = false; + $debugHandler = null; + + $this->getFunctionMock('Thrift\Transport', 'fsockopen') + ->expects($this->once()) + ->with( + $host, + $port, + $this->anything(), #$errno, + $this->anything(), #$errstr, + $this->anything() #$this->sendTimeoutSec_ + ($this->sendTimeoutUsec_ / 1000000), + ) + ->willReturn(fopen('php://input', 'r+')); + + $this->getFunctionMock('Thrift\Transport', 'socket_import_stream') + ->expects($this->once()) + ->willReturn($socketImportResult); + + $this->getFunctionMock('Thrift\Transport', 'socket_set_option') + ->expects($socketImportResult ? $this->once() : $this->never()) + ->with( + $this->anything(), #$socket, + SOL_TCP, #$level + TCP_NODELAY, #$option + 1 #$value + ) + ->willReturn(true); + + $transport = new TSocket( + $host, + $port, + $persist, + $debugHandler + ); + + $transport->open(); + $this->assertTrue($transport->isOpen()); + } + + public function open_THRIFT_5132_DataProvider() + { + yield 'socket_import_stream success' => [ + 'socketImportResult' => true, + ]; + yield 'socket_import_stream fail' => [ + 'socketImportResult' => false, + ]; + } + + public function testSetHandle() + { + $host = 'localhost'; + $port = 9090; + $persist = false; + $debugHandler = null; + $transport = new TSocket( + $host, + $port, + $persist, + $debugHandler + ); + + $this->assertFalse($transport->isOpen()); + $transport->setHandle(fopen('php://memory', 'r+')); + $this->assertTrue($transport->isOpen()); + } + + public function testSetSendTimeout() + { + $host = 'localhost'; + $port = 9090; + $persist = false; + $debugHandler = null; + $transport = new TSocket( + $host, + $port, + $persist, + $debugHandler + ); + + $transport->setSendTimeout(9999); + $reflector = new \ReflectionClass($transport); + $property = $reflector->getProperty('sendTimeoutSec_'); + $property->setAccessible(true); + $this->assertEquals(9.0, $property->getValue($transport)); + $property = $reflector->getProperty('sendTimeoutUsec_'); + $property->setAccessible(true); + $this->assertEquals(999000, $property->getValue($transport)); + } + + public function testSetRecvTimeout() + { + $host = 'localhost'; + $port = 9090; + $persist = false; + $debugHandler = null; + $transport = new TSocket( + $host, + $port, + $persist, + $debugHandler + ); + + $transport->setRecvTimeout(9999); + $reflector = new \ReflectionClass($transport); + $property = $reflector->getProperty('recvTimeoutSec_'); + $property->setAccessible(true); + $this->assertEquals(9.0, $property->getValue($transport)); + $property = $reflector->getProperty('recvTimeoutUsec_'); + $property->setAccessible(true); + $this->assertEquals(999000, $property->getValue($transport)); + } + + /** + * @dataProvider hostDataProvider + */ + public function testGetHost($host, $expected) + { + $port = 9090; + $persist = false; + $debugHandler = null; + $transport = new TSocket( + $host, + $port, + $persist, + $debugHandler + ); + $this->assertEquals($expected, $transport->getHost()); + } + + public function hostDataProvider() + { + yield 'localhost' => ['localhost', 'localhost']; + yield 'ssl_localhost' => ['ssl://localhost', 'ssl://localhost']; + yield 'http_localhost' => ['http://localhost', 'http://localhost']; + } + + public function testGetPort() + { + $host = 'localhost'; + $port = 9090; + $persist = false; + $debugHandler = null; + $transport = new TSocket( + $host, + $port, + $persist, + $debugHandler + ); + $this->assertEquals($port, $transport->getPort()); + } + + public function testClose() + { + $host = 'localhost'; + $port = 9090; + $persist = false; + $debugHandler = null; + $transport = new TSocket( + $host, + $port, + $persist, + $debugHandler + ); + $transport->setHandle(fopen('php://memory', 'r+')); + $reflector = new \ReflectionClass($transport); + $property = $reflector->getProperty('handle_'); + $property->setAccessible(true); + $this->assertNotNull($property->getValue($transport)); + + $transport->close(); + $reflector = new \ReflectionClass($transport); + $property = $reflector->getProperty('handle_'); + $property->setAccessible(true); + $this->assertNull($property->getValue($transport)); + } + + /** + * @dataProvider writeFailDataProvider + */ + public function testWriteFail( + $streamSelectResult, + $fwriteCallCount, + $expectedException, + $expectedMessage, + $expectedCode + ) { + $host = 'localhost'; + $port = 9090; + $persist = false; + $debugHandler = null; + $handle = fopen('php://memory', 'r+'); + + $this->getFunctionMock('Thrift\Transport', 'stream_select') + ->expects($this->once()) + ->with( + $this->anything(), #$null, + [$handle], + $this->anything(), #$null, + $this->anything(), #$this->sendTimeoutSec_, + $this->anything() #$this->sendTimeoutUsec_ + ) + ->willReturn($streamSelectResult); + + $this->getFunctionMock('Thrift\Transport', 'fwrite') + ->expects($this->exactly($fwriteCallCount)) + ->with( + $handle, + 'test1234456789132456798' + ) + ->willReturn(false); + + $this->expectException($expectedException); + $this->expectExceptionMessage($expectedMessage); + $this->expectExceptionCode($expectedCode); + + $transport = new TSocket( + $host, + $port, + $persist, + $debugHandler + ); + $transport->setHandle($handle); + + $transport->write('test1234456789132456798'); + } + + public function testWrite() + { + $host = 'localhost'; + $port = 9090; + $persist = false; + $debugHandler = null; + $transport = new TSocket( + $host, + $port, + $persist, + $debugHandler + ); + $fileName = sys_get_temp_dir() . '/' . md5(mt_rand(0, time()) . time()); + touch($fileName); + $handle = fopen($fileName, 'r+'); + $transport->setHandle($handle); + $transport->write('test1234456789132456798'); + $this->assertEquals('test1234456789132456798', file_get_contents($fileName)); + + register_shutdown_function(function () use ($fileName) { + is_file($fileName) && unlink($fileName); + }); + } + + public function writeFailDataProvider() + { + yield 'stream_select timeout' => [ + 'streamSelectResult' => 0, + 'fwriteCallCount' => 0, + 'expectedException' => TTransportException::class, + 'expectedMessage' => 'TSocket: timed out writing 23 bytes from localhost:9090', + 'expectedCode' => 0, + ]; + yield 'stream_select fail write' => [ + 'streamSelectResult' => 1, + 'fwriteCallCount' => 1, + 'expectedException' => TTransportException::class, + 'expectedMessage' => 'TSocket: Could not write 23 bytes localhost:9090', + 'expectedCode' => 0, + ]; + yield 'stream_select fail' => [ + 'streamSelectResult' => false, + 'fwriteCallCount' => 0, + 'expectedException' => TTransportException::class, + 'expectedMessage' => 'TSocket: Could not write 23 bytes localhost:9090', + 'expectedCode' => 0, + ]; + } + + public function testRead() + { + $host = 'localhost'; + $port = 9090; + $persist = false; + $debugHandler = null; + $transport = new TSocket( + $host, + $port, + $persist, + $debugHandler + ); + $fileName = sys_get_temp_dir() . '/' . md5(mt_rand(0, time()) . time()); + file_put_contents($fileName, '12345678901234567890'); + $handle = fopen($fileName, 'r+'); + $transport->setHandle($handle); + $this->assertEquals('12345', $transport->read(5)); + + register_shutdown_function(function () use ($fileName) { + is_file($fileName) && unlink($fileName); + }); + } + + /** + * @dataProvider readFailDataProvider + */ + public function testReadFail( + $streamSelectResult, + $freadResult, + $feofResult, + $expectedException, + $expectedMessage, + $expectedCode + ) { + $host = 'localhost'; + $port = 9090; + $persist = false; + $debugHandler = null; + $handle = fopen('php://memory', 'r+'); + + $this->getFunctionMock('Thrift\Transport', 'stream_select') + ->expects($this->once()) + ->with( + [$handle], + $this->anything(), #$null, + $this->anything(), #$null, + $this->anything(), #$this->recvTimeoutSec_, + $this->anything() #$this->recvTimeoutUsec_ + ) + ->willReturn($streamSelectResult); + + $this->getFunctionMock('Thrift\Transport', 'fread') + ->expects($this->exactly($streamSelectResult ? 1 : 0)) + ->with( + $handle, + 5 + ) + ->willReturn($freadResult); + $this->getFunctionMock('Thrift\Transport', 'feof') + ->expects($this->exactly($feofResult ? 1 : 0)) + ->with($handle) + ->willReturn($feofResult); + + $this->expectException($expectedException); + $this->expectExceptionMessage($expectedMessage); + $this->expectExceptionCode($expectedCode); + + $transport = new TSocket( + $host, + $port, + $persist, + $debugHandler + ); + $transport->setHandle($handle); + + $transport->read(5); + } + + public function readFailDataProvider() + { + yield 'stream_select timeout' => [ + 'streamSelectResult' => 0, + 'freadResult' => '', + 'feofResult' => false, + 'expectedException' => TTransportException::class, + 'expectedMessage' => 'TSocket: timed out reading 5 bytes from localhost:9090', + 'expectedCode' => 0, + ]; + yield 'stream_select fail read' => [ + 'streamSelectResult' => 1, + 'freadResult' => '', + 'feofResult' => true, + 'expectedException' => TTransportException::class, + 'expectedMessage' => 'TSocket read 0 bytes', + 'expectedCode' => 0, + ]; + yield 'stream_select fail' => [ + 'streamSelectResult' => false, + 'freadResult' => '', + 'feofResult' => false, + 'expectedException' => TTransportException::class, + 'expectedMessage' => 'TSocket: Could not read 5 bytes from localhost:9090', + 'expectedCode' => 0, + ]; + yield 'fread false' => [ + 'streamSelectResult' => 1, + 'freadResult' => false, + 'feofResult' => false, + 'expectedException' => TTransportException::class, + 'expectedMessage' => 'TSocket: Could not read 5 bytes from localhost:9090', + 'expectedCode' => 0, + ]; + yield 'fread empty' => [ + 'streamSelectResult' => 1, + 'freadResult' => '', + 'feofResult' => true, + 'expectedException' => TTransportException::class, + 'expectedMessage' => 'TSocket read 0 bytes', + 'expectedCode' => 0, + ]; + } + + public function testFlush() + { + $host = 'localhost'; + $port = 9090; + $persist = false; + $debugHandler = null; + $transport = new TSocket( + $host, + $port, + $persist, + $debugHandler + ); + $this->assertNUll($transport->flush()); + } +} diff --git a/lib/php/test/bootstrap.php b/lib/php/test/bootstrap.php new file mode 100644 index 00000000000..c6291e51798 --- /dev/null +++ b/lib/php/test/bootstrap.php @@ -0,0 +1,16 @@ +registerNamespace('Basic', __DIR__ . '/Resources/packages/php'); +$loader->registerNamespace('Validate', __DIR__ . '/Resources/packages/phpv'); +$loader->registerNamespace('ValidateOop', __DIR__ . '/Resources/packages/phpvo'); +$loader->registerNamespace('Json', __DIR__ . '/Resources/packages/phpjs'); + +#do not load this namespace here, it will be loaded in ClassLoaderTest +//$loader->registerNamespace('Server', __DIR__ . '/Resources/packages/phpcm'); + +$loader->register(); diff --git a/lib/py/Makefile.am b/lib/py/Makefile.am index 9b6d33b9acc..4777ccff8d9 100644 --- a/lib/py/Makefile.am +++ b/lib/py/Makefile.am @@ -45,7 +45,7 @@ all-local: py3-build # Old version (can't put inline because it's not portable). #$(PYTHON) setup.py install --prefix=$(prefix) --root=$(DESTDIR) $(PYTHON_SETUPUTIL_ARGS) install-exec-hook: - $(PYTHON) setup.py install --root=$(DESTDIR) --prefix=$(PY_PREFIX) $(PYTHON_SETUPUTIL_ARGS) + $(PYTHON) -m pip install . --root=$(DESTDIR) --prefix=$(PY_PREFIX) $(PYTHON_SETUPUTIL_ARGS) check-local: all py3-test $(PYTHON) test/thrift_json.py @@ -69,6 +69,9 @@ dist-hook: find $(distdir) -type f \( -iname "*.pyc" \) | xargs rm -f find $(distdir) -type d \( -iname "__pycache__" -or -iname "_trial_temp" \) | xargs rm -rf +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ CMakeLists.txt \ MANIFEST.in \ diff --git a/lib/py/setup.py b/lib/py/setup.py index f5371af753c..2a170a411cc 100644 --- a/lib/py/setup.py +++ b/lib/py/setup.py @@ -97,15 +97,13 @@ def run_setup(with_binary): extensions = dict() ssl_deps = [] - if sys.version_info[0] == 2: - ssl_deps.append('ipaddress') if sys.hexversion < 0x03050000: ssl_deps.append('backports.ssl_match_hostname>=3.5') tornado_deps = ['tornado>=4.0'] twisted_deps = ['twisted'] setup(name='thrift', - version='0.20.0', + version='0.22.0', description='Python bindings for the Apache Thrift RPC system', long_description=read_file("README.md"), long_description_content_type="text/markdown", @@ -113,7 +111,6 @@ def run_setup(with_binary): author_email='dev@thrift.apache.org', url='http://thrift.apache.org', license='Apache License 2.0', - install_requires=['six>=1.7.2'], extras_require={ 'ssl': ssl_deps, 'tornado': tornado_deps, @@ -132,7 +129,6 @@ def run_setup(with_binary): 'Environment :: Console', 'Intended Audience :: Developers', 'Programming Language :: Python', - 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 3', 'Topic :: Software Development :: Libraries', 'Topic :: System :: Networking' diff --git a/lib/py/src/TRecursive.py b/lib/py/src/TRecursive.py index abf202cb1eb..aed696ad993 100644 --- a/lib/py/src/TRecursive.py +++ b/lib/py/src/TRecursive.py @@ -10,11 +10,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function -from __future__ import unicode_literals - from thrift.Thrift import TType TYPE_IDX = 1 diff --git a/lib/py/src/TSCons.py b/lib/py/src/TSCons.py index bc67d7069b6..633f67ab008 100644 --- a/lib/py/src/TSCons.py +++ b/lib/py/src/TSCons.py @@ -19,7 +19,6 @@ from os import path from SCons.Builder import Builder -from six.moves import map def scons_env(env, add=''): diff --git a/lib/py/src/TTornado.py b/lib/py/src/TTornado.py index 5eff11d2d85..c7218301afd 100644 --- a/lib/py/src/TTornado.py +++ b/lib/py/src/TTornado.py @@ -17,10 +17,10 @@ # under the License. # -from __future__ import absolute_import import logging import socket import struct +import warnings from .transport.TTransport import TTransportException, TTransportBase, TMemoryBuffer @@ -34,7 +34,7 @@ logger = logging.getLogger(__name__) -class _Lock(object): +class _Lock: def __init__(self): self._waiters = deque() @@ -67,9 +67,19 @@ def _lock_context(self): class TTornadoStreamTransport(TTransportBase): """a framed, buffered transport over a Tornado stream""" def __init__(self, host, port, stream=None, io_loop=None): + if io_loop is not None: + warnings.warn( + "The `io_loop` parameter is deprecated and unused. Passing " + "`io_loop` is unnecessary because Tornado now automatically " + "provides the current I/O loop via `IOLoop.current()`. " + "Remove the `io_loop` parameter to ensure compatibility - it " + "will be removed in a future release.", + DeprecationWarning, + stacklevel=2, + ) self.host = host self.port = port - self.io_loop = io_loop or ioloop.IOLoop.current() + self.io_loop = ioloop.IOLoop.current() self.__wbuf = BytesIO() self._read_lock = _Lock() @@ -77,7 +87,12 @@ def __init__(self, host, port, stream=None, io_loop=None): self.stream = stream def with_timeout(self, timeout, future): - return gen.with_timeout(timeout, future, self.io_loop) + return gen.with_timeout(timeout, future) + + def isOpen(self): + if self.stream is None: + return False + return not self.stream.closed() @gen.coroutine def open(self, timeout=None): @@ -165,8 +180,7 @@ def __init__(self, processor, iprot_factory, oprot_factory=None, @gen.coroutine def handle_stream(self, stream, address): host, port = address[:2] - trans = TTornadoStreamTransport(host=host, port=port, stream=stream, - io_loop=self.io_loop) + trans = TTornadoStreamTransport(host=host, port=port, stream=stream) oprot = self._oprot_factory.getProtocol(trans) try: diff --git a/lib/py/src/protocol/TBinaryProtocol.py b/lib/py/src/protocol/TBinaryProtocol.py index 6b2facc4f72..af64ec10356 100644 --- a/lib/py/src/protocol/TBinaryProtocol.py +++ b/lib/py/src/protocol/TBinaryProtocol.py @@ -17,9 +17,10 @@ # under the License. # -from .TProtocol import TType, TProtocolBase, TProtocolException, TProtocolFactory from struct import pack, unpack +from .TProtocol import TType, TProtocolBase, TProtocolException, TProtocolFactory + class TBinaryProtocol(TProtocolBase): """Binary implementation of the Thrift protocol driver.""" @@ -145,7 +146,7 @@ def readMessageBegin(self): if self.strictRead: raise TProtocolException(type=TProtocolException.BAD_VERSION, message='No protocol version header') - name = self.trans.readAll(sz) + name = self.trans.readAll(sz).decode('utf-8') type = self.readByte() seqid = self.readI32() return (name, type, seqid) diff --git a/lib/py/src/protocol/TCompactProtocol.py b/lib/py/src/protocol/TCompactProtocol.py index 700e792f79b..a3527cd47a3 100644 --- a/lib/py/src/protocol/TCompactProtocol.py +++ b/lib/py/src/protocol/TCompactProtocol.py @@ -20,8 +20,6 @@ from .TProtocol import TType, TProtocolBase, TProtocolException, TProtocolFactory, checkIntegerLimits from struct import pack, unpack -from ..compat import binary_to_str, str_to_binary - __all__ = ['TCompactProtocol', 'TCompactProtocolFactory'] CLEAR = 0 @@ -165,7 +163,7 @@ def writeMessageBegin(self, name, type, seqid): if tseqid < 0: tseqid = 2147483648 + (2147483648 + tseqid) self.__writeVarint(tseqid) - self.__writeBinary(str_to_binary(name)) + self.__writeBinary(bytes(name, 'utf-8')) self.state = VALUE_WRITE def writeMessageEnd(self): @@ -346,7 +344,7 @@ def readMessageBegin(self): # however the sequence is actually signed... if seqid > 2147483647: seqid = -2147483648 - (2147483648 - seqid) - name = binary_to_str(self.__readBinary()) + name = self.__readBinary().decode('utf-8') return (name, type, seqid) def readMessageEnd(self): diff --git a/lib/py/src/protocol/TJSONProtocol.py b/lib/py/src/protocol/TJSONProtocol.py index 17417027a0a..a42aaa6315d 100644 --- a/lib/py/src/protocol/TJSONProtocol.py +++ b/lib/py/src/protocol/TJSONProtocol.py @@ -23,8 +23,6 @@ import math import sys -from ..compat import str_to_binary - __all__ = ['TJSONProtocol', 'TJSONProtocolFactory', @@ -213,7 +211,7 @@ def writeJSONString(self, string): escaped = ESCAPE_CHAR_VALS.get(s, s) json_str.append(escaped) json_str.append('"') - self.trans.write(str_to_binary(''.join(json_str))) + self.trans.write(bytes(''.join(json_str), 'utf-8')) def writeJSONNumber(self, number, formatter='{0}'): self.context.write() @@ -263,19 +261,11 @@ def _isLowSurrogate(self, codeunit): def _toChar(self, high, low=None): if not low: - if sys.version_info[0] == 2: - return ("\\u%04x" % high).decode('unicode-escape') \ - .encode('utf-8') - else: - return chr(high) + return chr(high) else: codepoint = (1 << 16) + ((high & 0x3ff) << 10) codepoint += low & 0x3ff - if sys.version_info[0] == 2: - s = "\\U%08x" % codepoint - return s.decode('unicode-escape').encode('utf-8') - else: - return chr(codepoint) + return chr(codepoint) def readJSONString(self, skipContext): highSurrogate = None @@ -317,11 +307,11 @@ def readJSONString(self, skipContext): elif character in ESCAPE_CHAR_VALS: raise TProtocolException(TProtocolException.INVALID_DATA, "Unescaped control char") - elif sys.version_info[0] > 2: + else: utf8_bytes = bytearray([ord(character)]) while ord(self.reader.peek()) >= 0x80: utf8_bytes.append(ord(self.reader.read())) - character = utf8_bytes.decode('utf8') + character = utf8_bytes.decode('utf-8') string.append(character) if highSurrogate: diff --git a/lib/py/src/protocol/TProtocol.py b/lib/py/src/protocol/TProtocol.py index 339a2839d71..5b4f4d85d81 100644 --- a/lib/py/src/protocol/TProtocol.py +++ b/lib/py/src/protocol/TProtocol.py @@ -19,12 +19,9 @@ from thrift.Thrift import TException, TType, TFrozenDict from thrift.transport.TTransport import TTransportException -from ..compat import binary_to_str, str_to_binary -import six import sys from itertools import islice -from six.moves import zip class TProtocolException(TException): @@ -119,14 +116,11 @@ def writeDouble(self, dub): pass def writeString(self, str_val): - self.writeBinary(str_to_binary(str_val)) + self.writeBinary(bytes(str_val, 'utf-8')) def writeBinary(self, str_val): pass - def writeUtf8(self, str_val): - self.writeString(str_val.encode('utf8')) - def readMessageBegin(self): pass @@ -182,14 +176,11 @@ def readDouble(self): pass def readString(self): - return binary_to_str(self.readBinary()) + return self.readBinary().decode('utf-8') def readBinary(self): pass - def readUtf8(self): - return self.readString().decode('utf8') - def skip(self, ttype): if ttype == TType.BOOL: self.readBool() @@ -263,11 +254,6 @@ def _ttype_handlers(self, ttype, spec): raise TProtocolException(type=TProtocolException.INVALID_DATA, message='Invalid binary field type %d' % ttype) return ('readBinary', 'writeBinary', False) - if sys.version_info[0] == 2 and spec == 'UTF8': - if ttype != TType.STRING: - raise TProtocolException(type=TProtocolException.INVALID_DATA, - message='Invalid string field type %d' % ttype) - return ('readUtf8', 'writeUtf8', False) return self._TTYPE_HANDLERS[ttype] if ttype < len(self._TTYPE_HANDLERS) else (None, None, False) def _read_by_ttype(self, ttype, spec, espec): @@ -373,8 +359,8 @@ def writeContainerSet(self, val, spec): def writeContainerMap(self, val, spec): ktype, kspec, vtype, vspec, _ = spec self.writeMapBegin(ktype, vtype, len(val)) - for _ in zip(self._write_by_ttype(ktype, six.iterkeys(val), spec, kspec), - self._write_by_ttype(vtype, six.itervalues(val), spec, vspec)): + for _ in zip(self._write_by_ttype(ktype, val.keys(), spec, kspec), + self._write_by_ttype(vtype, val.values(), spec, vspec)): pass self.writeMapEnd() diff --git a/lib/py/src/server/THttpServer.py b/lib/py/src/server/THttpServer.py index 47e817df773..21f2c869149 100644 --- a/lib/py/src/server/THttpServer.py +++ b/lib/py/src/server/THttpServer.py @@ -19,7 +19,7 @@ import ssl -from six.moves import BaseHTTPServer +import http.server as BaseHTTPServer from thrift.Thrift import TMessageType from thrift.server import TServer diff --git a/lib/py/src/server/TNonblockingServer.py b/lib/py/src/server/TNonblockingServer.py index 76947608f56..a7a40cafb53 100644 --- a/lib/py/src/server/TNonblockingServer.py +++ b/lib/py/src/server/TNonblockingServer.py @@ -32,7 +32,7 @@ import threading from collections import deque -from six.moves import queue +import queue from thrift.transport import TTransport from thrift.protocol.TBinaryProtocol import TBinaryProtocolFactory diff --git a/lib/py/src/server/TServer.py b/lib/py/src/server/TServer.py index 8b2f938a62a..81144f14a9b 100644 --- a/lib/py/src/server/TServer.py +++ b/lib/py/src/server/TServer.py @@ -17,7 +17,7 @@ # under the License. # -from six.moves import queue +import queue import logging import os import threading diff --git a/lib/py/src/transport/THeaderTransport.py b/lib/py/src/transport/THeaderTransport.py index 7c9827ba3a9..4fb20343020 100644 --- a/lib/py/src/transport/THeaderTransport.py +++ b/lib/py/src/transport/THeaderTransport.py @@ -19,8 +19,8 @@ import struct import zlib +from io import BytesIO -from thrift.compat import BufferIO, byte_index from thrift.protocol.TBinaryProtocol import TBinaryProtocol from thrift.protocol.TCompactProtocol import TCompactProtocol, readVarint, writeVarint from thrift.Thrift import TApplicationException @@ -31,7 +31,6 @@ TTransportException, ) - U16 = struct.Struct("!H") I32 = struct.Struct("!i") HEADER_MAGIC = 0x0FFF @@ -92,10 +91,10 @@ def __init__(self, transport, allowed_client_types, default_protocol=THeaderSubp self._client_type = THeaderClientType.HEADERS self._allowed_client_types = allowed_client_types - self._read_buffer = BufferIO(b"") + self._read_buffer = BytesIO(b"") self._read_headers = {} - self._write_buffer = BufferIO() + self._write_buffer = BytesIO() self._write_headers = {} self._write_transforms = [] @@ -184,8 +183,8 @@ def readFrame(self, req_sz): if frame_size & TBinaryProtocol.VERSION_MASK == TBinaryProtocol.VERSION_1: self._set_client_type(THeaderClientType.UNFRAMED_BINARY) is_unframed = True - elif (byte_index(first_word, 0) == TCompactProtocol.PROTOCOL_ID and - byte_index(first_word, 1) & TCompactProtocol.VERSION_MASK == TCompactProtocol.VERSION): + elif (first_word[0] == TCompactProtocol.PROTOCOL_ID and + first_word[1] & TCompactProtocol.VERSION_MASK == TCompactProtocol.VERSION): self._set_client_type(THeaderClientType.UNFRAMED_COMPACT) is_unframed = True @@ -195,7 +194,7 @@ def readFrame(self, req_sz): rest = self._transport.read(bytes_left_to_read) else: rest = b"" - self._read_buffer = BufferIO(first_word + rest) + self._read_buffer = BytesIO(first_word + rest) return # ok, we're still here so we're framed. @@ -204,7 +203,7 @@ def readFrame(self, req_sz): TTransportException.SIZE_LIMIT, "Frame was too large.", ) - read_buffer = BufferIO(self._transport.readAll(frame_size)) + read_buffer = BytesIO(self._transport.readAll(frame_size)) # the next word is either going to be the version field of a # binary/compact protocol message or the magic value + flags of a @@ -218,8 +217,8 @@ def readFrame(self, req_sz): elif version & TBinaryProtocol.VERSION_MASK == TBinaryProtocol.VERSION_1: self._set_client_type(THeaderClientType.FRAMED_BINARY) self._read_buffer = read_buffer - elif (byte_index(second_word, 0) == TCompactProtocol.PROTOCOL_ID and - byte_index(second_word, 1) & TCompactProtocol.VERSION_MASK == TCompactProtocol.VERSION): + elif (second_word[0] == TCompactProtocol.PROTOCOL_ID and + second_word[1] & TCompactProtocol.VERSION_MASK == TCompactProtocol.VERSION): self._set_client_type(THeaderClientType.FRAMED_COMPACT) self._read_buffer = read_buffer else: @@ -229,7 +228,7 @@ def readFrame(self, req_sz): ) def _parse_header_format(self, buffer): - # make BufferIO look like TTransport for varint helpers + # make BytesIO look like TTransport for varint helpers buffer_transport = TMemoryBuffer() buffer_transport._buffer = buffer @@ -279,22 +278,22 @@ def _parse_header_format(self, buffer): for transform_id in transforms: transform_fn = READ_TRANSFORMS_BY_ID[transform_id] payload = transform_fn(payload) - return BufferIO(payload) + return BytesIO(payload) def write(self, buf): self._write_buffer.write(buf) def flush(self): payload = self._write_buffer.getvalue() - self._write_buffer = BufferIO() + self._write_buffer = BytesIO() - buffer = BufferIO() + buffer = BytesIO() if self._client_type == THeaderClientType.HEADERS: for transform_id in self._write_transforms: transform_fn = WRITE_TRANSFORMS_BY_ID[transform_id] payload = transform_fn(payload) - headers = BufferIO() + headers = BytesIO() writeVarint(headers, self._protocol_id) writeVarint(headers, len(self._write_transforms)) for transform_id in self._write_transforms: @@ -348,5 +347,5 @@ def cstringio_refill(self, partialread, reqlen): result = bytearray(partialread) while len(result) < reqlen: result += self.read(reqlen - len(result)) - self._read_buffer = BufferIO(result) + self._read_buffer = BytesIO(result) return self._read_buffer diff --git a/lib/py/src/transport/THttpClient.py b/lib/py/src/transport/THttpClient.py index 82ca3d12dfb..cda5f83d462 100644 --- a/lib/py/src/transport/THttpClient.py +++ b/lib/py/src/transport/THttpClient.py @@ -24,11 +24,11 @@ import warnings import base64 -from six.moves import urllib -from six.moves import http_client +import urllib.parse +import urllib.request +import http.client from .TTransport import TTransportBase -import six class THttpClient(TTransportBase): @@ -60,9 +60,9 @@ def __init__(self, uri_or_host, port=None, path=None, cafile=None, cert_file=Non self.scheme = parsed.scheme assert self.scheme in ('http', 'https') if self.scheme == 'http': - self.port = parsed.port or http_client.HTTP_PORT + self.port = parsed.port or http.client.HTTP_PORT elif self.scheme == 'https': - self.port = parsed.port or http_client.HTTPS_PORT + self.port = parsed.port or http.client.HTTPS_PORT self.certfile = cert_file self.keyfile = key_file self.context = ssl.create_default_context(cafile=cafile) if (cafile and not ssl_context) else ssl_context @@ -107,12 +107,10 @@ def using_proxy(self): def open(self): if self.scheme == 'http': - self.__http = http_client.HTTPConnection(self.host, self.port, + self.__http = http.client.HTTPConnection(self.host, self.port, timeout=self.__timeout) elif self.scheme == 'https': - self.__http = http_client.HTTPSConnection(self.host, self.port, - key_file=self.keyfile, - cert_file=self.certfile, + self.__http = http.client.HTTPSConnection(self.host, self.port, timeout=self.__timeout, context=self.context) if self.using_proxy(): @@ -173,7 +171,7 @@ def flush(self): self.__http.putheader('User-Agent', user_agent) if self.__custom_headers: - for key, val in six.iteritems(self.__custom_headers): + for key, val in self.__custom_headers.items(): self.__http.putheader(key, val) # Saves the cookie sent by the server in the previous response. diff --git a/lib/py/src/transport/TSSLSocket.py b/lib/py/src/transport/TSSLSocket.py index 5b3ae599194..d3263c6c77a 100644 --- a/lib/py/src/transport/TSSLSocket.py +++ b/lib/py/src/transport/TSSLSocket.py @@ -24,10 +24,12 @@ import sys import warnings -from .sslcompat import _match_hostname, _match_has_ipaddress +from .sslcompat import _match_has_ipaddress from thrift.transport import TSocket from thrift.transport.TTransport import TTransportException +_match_hostname = lambda cert, hostname: True + logger = logging.getLogger(__name__) warnings.filterwarnings( 'default', category=DeprecationWarning, module=__name__) @@ -45,7 +47,7 @@ class TSSLBase(object): # SSL 2.0 and 3.0 are disabled via ssl.OP_NO_SSLv2 and ssl.OP_NO_SSLv3. # For python < 2.7.9, use TLS 1.0 since TLSv1_X nor OP_NO_SSLvX is # unavailable. - _default_protocol = ssl.PROTOCOL_SSLv23 if _has_ssl_context else \ + _default_protocol = ssl.PROTOCOL_TLS_CLIENT if _has_ssl_context else \ ssl.PROTOCOL_TLSv1 def _init_context(self, ssl_version): @@ -397,8 +399,8 @@ def accept(self): self._validate_callback(client.peercert, addr[0]) client.is_valid = True except Exception: - logger.warn('Failed to validate client certificate address: %s', - addr[0], exc_info=True) + logger.warning('Failed to validate client certificate address: %s', + addr[0], exc_info=True) client.close() plain_client.close() return None diff --git a/lib/py/src/transport/TSocket.py b/lib/py/src/transport/TSocket.py index 50ee67e7665..51ea7e33014 100644 --- a/lib/py/src/transport/TSocket.py +++ b/lib/py/src/transport/TSocket.py @@ -90,18 +90,22 @@ def isOpen(self): self.handle.settimeout(0) try: peeked_bytes = self.handle.recv(1, socket.MSG_PEEK) + # the length will be zero if we got EOF (indicating connection closed) + if len(peeked_bytes) == 1: + return True except (socket.error, OSError) as exc: # on modern python this is just BlockingIOError if exc.errno in (errno.EWOULDBLOCK, errno.EAGAIN): return True - return False except ValueError: # SSLSocket fails on recv with non-zero flags; fallback to the old behavior return True finally: self.handle.settimeout(original_timeout) - # the length will be zero if we got EOF (indicating connection closed) - return len(peeked_bytes) == 1 + # The caller may assume that after isOpen() returns False, calling close() + # is not needed, so it is safer to close the socket here. + self.close() + return False def setTimeout(self, ms): if ms is None: @@ -151,6 +155,8 @@ def open(self): def read(self, sz): try: buff = self.handle.recv(sz) + except socket.timeout as e: + raise TTransportException(type=TTransportException.TIMED_OUT, message="read timeout", inner=e) except socket.error as e: if (e.args[0] == errno.ECONNRESET and (sys.platform == 'darwin' or sys.platform.startswith('freebsd'))): @@ -161,8 +167,6 @@ def read(self, sz): self.close() # Trigger the check to raise the END_OF_FILE exception below. buff = '' - elif e.args[0] == errno.ETIMEDOUT: - raise TTransportException(type=TTransportException.TIMED_OUT, message="read timeout", inner=e) else: raise TTransportException(message="unexpected exception", inner=e) if len(buff) == 0: @@ -208,7 +212,7 @@ def setBacklog(self, backlog=None): else: # We cann't update backlog when it is already listening, since the # handle has been created. - logger.warn('You have to set backlog before listen.') + logger.warning('You have to set backlog before listen.') def listen(self): res0 = self._resolveAddr() diff --git a/lib/py/src/transport/TTransport.py b/lib/py/src/transport/TTransport.py index ff20d7ec99b..4f6b67fe123 100644 --- a/lib/py/src/transport/TTransport.py +++ b/lib/py/src/transport/TTransport.py @@ -17,9 +17,10 @@ # under the License. # +from io import BytesIO from struct import pack, unpack + from thrift.Thrift import TException -from ..compat import BufferIO class TTransportException(TException): @@ -143,9 +144,9 @@ class TBufferedTransport(TTransportBase, CReadableTransport): def __init__(self, trans, rbuf_size=DEFAULT_BUFFER): self.__trans = trans - self.__wbuf = BufferIO() + self.__wbuf = BytesIO() # Pass string argument to initialize read buffer as cStringIO.InputType - self.__rbuf = BufferIO(b'') + self.__rbuf = BytesIO(b'') self.__rbuf_size = rbuf_size def isOpen(self): @@ -161,7 +162,7 @@ def read(self, sz): ret = self.__rbuf.read(sz) if len(ret) != 0: return ret - self.__rbuf = BufferIO(self.__trans.read(max(sz, self.__rbuf_size))) + self.__rbuf = BytesIO(self.__trans.read(max(sz, self.__rbuf_size))) return self.__rbuf.read(sz) def write(self, buf): @@ -169,13 +170,13 @@ def write(self, buf): self.__wbuf.write(buf) except Exception as e: # on exception reset wbuf so it doesn't contain a partial function call - self.__wbuf = BufferIO() + self.__wbuf = BytesIO() raise e def flush(self): out = self.__wbuf.getvalue() # reset wbuf before write/flush to preserve state on underlying failure - self.__wbuf = BufferIO() + self.__wbuf = BytesIO() self.__trans.write(out) self.__trans.flush() @@ -194,7 +195,7 @@ def cstringio_refill(self, partialread, reqlen): if len(retstring) < reqlen: retstring += self.__trans.readAll(reqlen - len(retstring)) - self.__rbuf = BufferIO(retstring) + self.__rbuf = BytesIO(retstring) return self.__rbuf @@ -213,9 +214,9 @@ def __init__(self, value=None, offset=0): If value is set, this will be a transport for reading, otherwise, it is for writing""" if value is not None: - self._buffer = BufferIO(value) + self._buffer = BytesIO(value) else: - self._buffer = BufferIO() + self._buffer = BytesIO() if offset: self._buffer.seek(offset) @@ -263,8 +264,8 @@ class TFramedTransport(TTransportBase, CReadableTransport): def __init__(self, trans,): self.__trans = trans - self.__rbuf = BufferIO(b'') - self.__wbuf = BufferIO() + self.__rbuf = BytesIO(b'') + self.__wbuf = BytesIO() def isOpen(self): return self.__trans.isOpen() @@ -286,7 +287,7 @@ def read(self, sz): def readFrame(self): buff = self.__trans.readAll(4) sz, = unpack('!i', buff) - self.__rbuf = BufferIO(self.__trans.readAll(sz)) + self.__rbuf = BytesIO(self.__trans.readAll(sz)) def write(self, buf): self.__wbuf.write(buf) @@ -295,7 +296,7 @@ def flush(self): wout = self.__wbuf.getvalue() wsz = len(wout) # reset wbuf before write/flush to preserve state on underlying failure - self.__wbuf = BufferIO() + self.__wbuf = BytesIO() # N.B.: Doing this string concatenation is WAY cheaper than making # two separate calls to the underlying socket object. Socket writes in # Python turn out to be REALLY expensive, but it seems to do a pretty @@ -316,7 +317,7 @@ def cstringio_refill(self, prefix, reqlen): while len(prefix) < reqlen: self.readFrame() prefix += self.__rbuf.getvalue() - self.__rbuf = BufferIO(prefix) + self.__rbuf = BytesIO(prefix) return self.__rbuf @@ -370,8 +371,8 @@ def __init__(self, transport, host, service, mechanism='GSSAPI', self.transport = transport self.sasl = SASLClient(host, service, mechanism, **sasl_kwargs) - self.__wbuf = BufferIO() - self.__rbuf = BufferIO(b'') + self.__wbuf = BytesIO() + self.__rbuf = BytesIO(b'') def open(self): if not self.transport.isOpen(): @@ -423,7 +424,7 @@ def flush(self): encoded = self.sasl.wrap(data) self.transport.write(pack("!i", len(encoded)) + encoded) self.transport.flush() - self.__wbuf = BufferIO() + self.__wbuf = BytesIO() def read(self, sz): ret = self.__rbuf.read(sz) @@ -437,7 +438,7 @@ def _read_frame(self): header = self.transport.readAll(4) length, = unpack('!i', header) encoded = self.transport.readAll(length) - self.__rbuf = BufferIO(self.sasl.unwrap(encoded)) + self.__rbuf = BytesIO(self.sasl.unwrap(encoded)) def close(self): self.sasl.dispose() @@ -455,5 +456,5 @@ def cstringio_refill(self, prefix, reqlen): while len(prefix) < reqlen: self._read_frame() prefix += self.__rbuf.getvalue() - self.__rbuf = BufferIO(prefix) + self.__rbuf = BytesIO(prefix) return self.__rbuf diff --git a/lib/py/src/transport/TZlibTransport.py b/lib/py/src/transport/TZlibTransport.py index e8485792464..a476d2a0aae 100644 --- a/lib/py/src/transport/TZlibTransport.py +++ b/lib/py/src/transport/TZlibTransport.py @@ -22,13 +22,13 @@ data compression. """ -from __future__ import division import zlib +from io import BytesIO + from .TTransport import TTransportBase, CReadableTransport -from ..compat import BufferIO -class TZlibTransportFactory(object): +class TZlibTransportFactory: """Factory transport that builds zlib compressed transports. This factory caches the last single client/transport that it was passed @@ -88,8 +88,8 @@ def __init__(self, trans, compresslevel=9): """ self.__trans = trans self.compresslevel = compresslevel - self.__rbuf = BufferIO() - self.__wbuf = BufferIO() + self.__rbuf = BytesIO() + self.__wbuf = BytesIO() self._init_zlib() self._init_stats() @@ -97,8 +97,8 @@ def _reinit_buffers(self): """Internal method to initialize/reset the internal StringIO objects for read and write buffers. """ - self.__rbuf = BufferIO() - self.__wbuf = BufferIO() + self.__rbuf = BytesIO() + self.__wbuf = BytesIO() def _init_stats(self): """Internal method to reset the internal statistics counters @@ -203,7 +203,7 @@ def readComp(self, sz): self.bytes_in += len(zbuf) self.bytes_in_comp += len(buf) old = self.__rbuf.read() - self.__rbuf = BufferIO(old + buf) + self.__rbuf = BytesIO(old + buf) if len(old) + len(buf) == 0: return False return True @@ -228,7 +228,7 @@ def flush(self): ztail = self._zcomp_write.flush(zlib.Z_SYNC_FLUSH) self.bytes_out_comp += len(ztail) if (len(zbuf) + len(ztail)) > 0: - self.__wbuf = BufferIO() + self.__wbuf = BytesIO() self.__trans.write(zbuf + ztail) self.__trans.flush() @@ -244,5 +244,5 @@ def cstringio_refill(self, partialread, reqlen): retstring += self.read(self.DEFAULT_BUFFSIZE) while len(retstring) < reqlen: retstring += self.read(reqlen - len(retstring)) - self.__rbuf = BufferIO(retstring) + self.__rbuf = BytesIO(retstring) return self.__rbuf diff --git a/lib/py/src/transport/sslcompat.py b/lib/py/src/transport/sslcompat.py index ab00cb2a839..54235ec6d1d 100644 --- a/lib/py/src/transport/sslcompat.py +++ b/lib/py/src/transport/sslcompat.py @@ -70,7 +70,7 @@ def _optional_dependencies(): logger.debug('ipaddress module is available') ipaddr = True except ImportError: - logger.warn('ipaddress module is unavailable') + logger.warning('ipaddress module is unavailable') ipaddr = False if sys.hexversion < 0x030500F0: @@ -82,18 +82,25 @@ def _optional_dependencies(): if ver[0] * 10 + ver[1] >= 35: return ipaddr, match else: - logger.warn('backports.ssl_match_hostname module is too old') + logger.warning('backports.ssl_match_hostname module is too old') ipaddr = False except ImportError: - logger.warn('backports.ssl_match_hostname is unavailable') + logger.warning('backports.ssl_match_hostname is unavailable') ipaddr = False try: from ssl import match_hostname logger.debug('ssl.match_hostname is available') match = match_hostname except ImportError: - logger.warn('using legacy validation callback') - match = legacy_validate_callback + # https://docs.python.org/3/whatsnew/3.12.html: + # "Remove the ssl.match_hostname() function. It was deprecated in Python + # 3.7. OpenSSL performs hostname matching since Python 3.7, Python no + # longer uses the ssl.match_hostname() function."" + if sys.version_info[0] > 3 or (sys.version_info[0] == 3 and sys.version_info[1] >= 12): + match = lambda cert, hostname: True + else: + logger.warning('using legacy validation callback') + match = legacy_validate_callback return ipaddr, match diff --git a/lib/py/test/test_socket.py b/lib/py/test/test_socket.py index b732653a4d2..13c1d5113c9 100644 --- a/lib/py/test/test_socket.py +++ b/lib/py/test/test_socket.py @@ -11,6 +11,24 @@ class TSocketTest(unittest.TestCase): + def test_socket_readtimeout_exception(self): + acc = ServerAcceptor(TServerSocket(port=0)) + acc.start() + + sock = TSocket(host="localhost", port=acc.port) + sock.open() + sock.setTimeout(1) + sock.write(b"sleep") + + with self.assertRaises(TTransportException) as ctx: + sock.read(5) + exc = ctx.exception + self.assertEqual(exc.message, "read timeout") + + acc.client.close() # this also blocks until the other thread is done + acc.close() + sock.close() + def test_isOpen_checks_for_readability(self): # https://docs.python.org/3/library/socket.html#notes-on-socket-timeouts # https://docs.python.org/3/library/socket.html#socket.socket.settimeout @@ -49,9 +67,11 @@ def test_isOpen_checks_for_readability(self): # once the server side closes, it no longer shows open acc.client.close() # this also blocks until the other thread is done acc.close() - self.assertFalse(sock.isOpen()) - sock.close() + self.assertIsNotNone(sock.handle) + self.assertFalse(sock.isOpen()) + # after isOpen() returned False the socket should be closed (THRIFT-5813) + self.assertIsNone(sock.handle) if __name__ == "__main__": diff --git a/lib/py/test/test_sslsocket.py b/lib/py/test/test_sslsocket.py index a5ea06ae9e4..2cbf5f8dde2 100644 --- a/lib/py/test/test_sslsocket.py +++ b/lib/py/test/test_sslsocket.py @@ -19,6 +19,7 @@ import inspect import logging +import time import os import platform import ssl @@ -76,7 +77,9 @@ def run(self): try: self._client = self._server.accept() if self._client: - self._client.read(5) # hello + data = self._client.read(5) # hello/sleep + if data == b"sleep": + time.sleep(2) self._client.write(b"there") except Exception: logging.exception('error on server side (%s):' % self.name) diff --git a/lib/py/test/thrift_TBinaryProtocol.py b/lib/py/test/thrift_TBinaryProtocol.py index f7d05ff975d..b257626b1f8 100644 --- a/lib/py/test/thrift_TBinaryProtocol.py +++ b/lib/py/test/thrift_TBinaryProtocol.py @@ -152,15 +152,19 @@ def testField(type, data): protocol.readStructEnd() -def testMessage(data): +def testMessage(data, strict=True): message = {} message['name'] = data[0] message['type'] = data[1] message['seqid'] = data[2] + strictRead, strictWrite = True, True + if not strict: + strictRead, strictWrite = False, False + buf = TTransport.TMemoryBuffer() transport = TTransport.TBufferedTransportFactory().getTransport(buf) - protocol = TBinaryProtocol(transport) + protocol = TBinaryProtocol(transport, strictRead=strictRead, strictWrite=strictWrite) protocol.writeMessageBegin(message['name'], message['type'], message['seqid']) protocol.writeMessageEnd() @@ -169,7 +173,7 @@ def testMessage(data): buf = TTransport.TMemoryBuffer(data_r) transport = TTransport.TBufferedTransportFactory().getTransport(buf) - protocol = TBinaryProtocol(transport) + protocol = TBinaryProtocol(transport, strictRead=strictRead, strictWrite=strictWrite) result = protocol.readMessageBegin() protocol.readMessageEnd() return result @@ -259,6 +263,24 @@ def test_TBinaryProtocol_write_read(self): print("Assertion fail") raise e + def test_TBinaryProtocol_no_strict_write_read(self): + TMessageType = {"T_CALL": 1, "T_REPLY": 2, "T_EXCEPTION": 3, "T_ONEWAY": 4} + test_data = [("short message name", TMessageType['T_CALL'], 0), + ("1", TMessageType['T_REPLY'], 12345), + ("loooooooooooooooooooooooooooooooooong", TMessageType['T_EXCEPTION'], 1 << 16), + ("one way push", TMessageType['T_ONEWAY'], 12), + ("Janky", TMessageType['T_CALL'], 0)] + + try: + for dt in test_data: + result = testMessage(dt, strict=False) + self.assertEqual(result[0], dt[0]) + self.assertEqual(result[1], dt[1]) + self.assertEqual(result[2], dt[2]) + except Exception as e: + print("Assertion fail") + raise e + if __name__ == '__main__': unittest.main() diff --git a/lib/py/test/thrift_json.py b/lib/py/test/thrift_json.py index 125ea59f6c7..bf2b8086170 100644 --- a/lib/py/test/thrift_json.py +++ b/lib/py/test/thrift_json.py @@ -17,7 +17,6 @@ # under the License. # -import sys import unittest import _import_local_thrift # noqa @@ -42,8 +41,6 @@ def test_escaped_unicode_string(self): transport = TTransport.TBufferedTransportFactory().getTransport(buf) protocol = TJSONProtocol(transport) - if sys.version_info[0] == 2: - unicode_text = unicode_text.encode('utf8') self.assertEqual(protocol.readString(), unicode_text) def test_TJSONProtocol_write(self): diff --git a/lib/rb/Makefile.am b/lib/rb/Makefile.am index 1841065f5a3..ab5d903fe2a 100644 --- a/lib/rb/Makefile.am +++ b/lib/rb/Makefile.am @@ -42,6 +42,9 @@ endif dist-hook: $(RM) -r $(distdir)/spec/gen-rb/ +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ coding_standards.md \ Rakefile \ diff --git a/lib/rb/ext/binary_protocol_accelerated.c b/lib/rb/ext/binary_protocol_accelerated.c index 65cbe5ffecd..c9ae4d299bb 100644 --- a/lib/rb/ext/binary_protocol_accelerated.c +++ b/lib/rb/ext/binary_protocol_accelerated.c @@ -82,7 +82,7 @@ static void write_string_direct(VALUE trans, VALUE str) { rb_raise(rb_eStandardError, "Value should be a string"); } str = convert_to_utf8_byte_buffer(str); - write_i32_direct(trans, RSTRING_LEN(str)); + write_i32_direct(trans, (int32_t)RSTRING_LEN(str)); rb_funcall(trans, write_method_id, 1, str); } @@ -223,7 +223,7 @@ VALUE rb_thrift_binary_proto_write_binary(VALUE self, VALUE buf) { CHECK_NIL(buf); VALUE trans = GET_TRANSPORT(self); buf = force_binary_encoding(buf); - write_i32_direct(trans, RSTRING_LEN(buf)); + write_i32_direct(trans, (int32_t)RSTRING_LEN(buf)); rb_funcall(trans, write_method_id, 1, buf); return Qnil; } @@ -403,9 +403,9 @@ VALUE rb_thrift_binary_proto_read_binary(VALUE self) { void Init_binary_protocol_accelerated() { VALUE thrift_binary_protocol_class = rb_const_get(thrift_module, rb_intern("BinaryProtocol")); - VERSION_1 = rb_num2ll(rb_const_get(thrift_binary_protocol_class, rb_intern("VERSION_1"))); - VERSION_MASK = rb_num2ll(rb_const_get(thrift_binary_protocol_class, rb_intern("VERSION_MASK"))); - TYPE_MASK = rb_num2ll(rb_const_get(thrift_binary_protocol_class, rb_intern("TYPE_MASK"))); + VERSION_1 = (int)rb_num2ll(rb_const_get(thrift_binary_protocol_class, rb_intern("VERSION_1"))); + VERSION_MASK = (int)rb_num2ll(rb_const_get(thrift_binary_protocol_class, rb_intern("VERSION_MASK"))); + TYPE_MASK = (int)rb_num2ll(rb_const_get(thrift_binary_protocol_class, rb_intern("TYPE_MASK"))); VALUE bpa_class = rb_define_class_under(thrift_module, "BinaryProtocolAccelerated", thrift_binary_protocol_class); diff --git a/lib/rb/ext/compact_protocol.c b/lib/rb/ext/compact_protocol.c index fab2170a215..c98c09eb491 100644 --- a/lib/rb/ext/compact_protocol.c +++ b/lib/rb/ext/compact_protocol.c @@ -315,7 +315,7 @@ VALUE rb_thrift_compact_proto_write_string(VALUE self, VALUE str) { VALUE rb_thrift_compact_proto_write_binary(VALUE self, VALUE buf) { buf = force_binary_encoding(buf); VALUE transport = GET_TRANSPORT(self); - write_varint32(transport, RSTRING_LEN(buf)); + write_varint32(transport, (uint32_t)RSTRING_LEN(buf)); WRITE(transport, StringValuePtr(buf), RSTRING_LEN(buf)); return Qnil; } @@ -452,7 +452,7 @@ VALUE rb_thrift_compact_proto_read_message_begin(VALUE self) { } int8_t type = (version_and_type >> TYPE_SHIFT_AMOUNT) & TYPE_BITS; - int32_t seqid = read_varint64(self); + int32_t seqid = (int32_t)read_varint64(self); VALUE messageName = rb_thrift_compact_proto_read_string(self); return rb_ary_new3(3, messageName, INT2FIX(type), INT2NUM(seqid)); } @@ -490,7 +490,7 @@ VALUE rb_thrift_compact_proto_read_field_begin(VALUE self) { } VALUE rb_thrift_compact_proto_read_map_begin(VALUE self) { - int32_t size = read_varint64(self); + int32_t size = (int32_t)read_varint64(self); uint8_t key_and_value_type = size == 0 ? 0 : read_byte_direct(self); return rb_ary_new3(3, INT2FIX(get_ttype(key_and_value_type >> 4)), INT2FIX(get_ttype(key_and_value_type & 0xf)), INT2FIX(size)); } @@ -499,7 +499,7 @@ VALUE rb_thrift_compact_proto_read_list_begin(VALUE self) { uint8_t size_and_type = read_byte_direct(self); int32_t size = (size_and_type >> 4) & 0x0f; if (size == 15) { - size = read_varint64(self); + size = (int32_t)read_varint64(self); } uint8_t type = get_ttype(size_and_type & 0x0f); return rb_ary_new3(2, INT2FIX(type), INT2FIX(size)); @@ -528,7 +528,7 @@ VALUE rb_thrift_compact_proto_read_i16(VALUE self) { } VALUE rb_thrift_compact_proto_read_i32(VALUE self) { - return INT2NUM(zig_zag_to_int(read_varint64(self))); + return INT2NUM(zig_zag_to_int((int32_t)read_varint64(self))); } VALUE rb_thrift_compact_proto_read_i64(VALUE self) { @@ -569,10 +569,10 @@ static void Init_constants() { thrift_compact_protocol_class = rb_const_get(thrift_module, rb_intern("CompactProtocol")); rb_global_variable(&thrift_compact_protocol_class); - VERSION = rb_num2ll(rb_const_get(thrift_compact_protocol_class, rb_intern("VERSION"))); - VERSION_MASK = rb_num2ll(rb_const_get(thrift_compact_protocol_class, rb_intern("VERSION_MASK"))); - TYPE_MASK = rb_num2ll(rb_const_get(thrift_compact_protocol_class, rb_intern("TYPE_MASK"))); - TYPE_BITS = rb_num2ll(rb_const_get(thrift_compact_protocol_class, rb_intern("TYPE_BITS"))); + VERSION = (int32_t)rb_num2ll(rb_const_get(thrift_compact_protocol_class, rb_intern("VERSION"))); + VERSION_MASK = (int32_t)rb_num2ll(rb_const_get(thrift_compact_protocol_class, rb_intern("VERSION_MASK"))); + TYPE_MASK = (int32_t)rb_num2ll(rb_const_get(thrift_compact_protocol_class, rb_intern("TYPE_MASK"))); + TYPE_BITS = (int32_t)rb_num2ll(rb_const_get(thrift_compact_protocol_class, rb_intern("TYPE_BITS"))); TYPE_SHIFT_AMOUNT = FIX2INT(rb_const_get(thrift_compact_protocol_class, rb_intern("TYPE_SHIFT_AMOUNT"))); PROTOCOL_ID = FIX2INT(rb_const_get(thrift_compact_protocol_class, rb_intern("PROTOCOL_ID"))); diff --git a/lib/rb/ext/memory_buffer.c b/lib/rb/ext/memory_buffer.c index 8b52c4a3e0e..96604af8639 100644 --- a/lib/rb/ext/memory_buffer.c +++ b/lib/rb/ext/memory_buffer.c @@ -54,7 +54,7 @@ VALUE rb_thrift_memory_buffer_read(VALUE self, VALUE length_value) { index += length; if (index > RSTRING_LEN(buf)) { - index = RSTRING_LEN(buf); + index = (int)RSTRING_LEN(buf); } if (index >= GARBAGE_BUFFER_SIZE) { rb_ivar_set(self, buf_ivar_id, rb_funcall(buf, slice_method_id, 2, INT2FIX(index), INT2FIX(RSTRING_LEN(buf) - 1))); diff --git a/lib/rb/ext/struct.c b/lib/rb/ext/struct.c index 79cbabee7b9..e8255a9cbbf 100644 --- a/lib/rb/ext/struct.c +++ b/lib/rb/ext/struct.c @@ -225,7 +225,7 @@ VALUE get_field_value(VALUE obj, VALUE field_name) { } static void write_container(int ttype, VALUE field_info, VALUE value, VALUE protocol) { - int sz, i; + long sz, i; if (ttype == TTYPE_MAP) { VALUE keys; diff --git a/lib/rb/thrift.gemspec b/lib/rb/thrift.gemspec index 6b510c78be9..625c6a458b3 100644 --- a/lib/rb/thrift.gemspec +++ b/lib/rb/thrift.gemspec @@ -3,7 +3,7 @@ $:.push File.expand_path("../lib", __FILE__) Gem::Specification.new do |s| s.name = 'thrift' - s.version = '0.20.0' + s.version = '0.22.0' s.authors = ['Apache Thrift Developers'] s.email = ['dev@thrift.apache.org'] s.homepage = 'http://thrift.apache.org' @@ -12,7 +12,6 @@ Gem::Specification.new do |s| s.license = 'Apache-2.0' s.extensions = ['ext/extconf.rb'] - s.has_rdoc = true s.rdoc_options = %w[--line-numbers --inline-source --title Thrift --main README] s.rubyforge_project = 'thrift' diff --git a/lib/rs/Cargo.toml b/lib/rs/Cargo.toml index a6e8533aa57..263b9d972fc 100644 --- a/lib/rs/Cargo.toml +++ b/lib/rs/Cargo.toml @@ -2,7 +2,7 @@ name = "thrift" description = "Rust bindings for the Apache Thrift RPC system" edition = "2021" -version = "0.20.0" +version = "0.22.0" license = "Apache-2.0" authors = ["Apache Thrift Developers "] homepage = "http://thrift.apache.org" diff --git a/lib/rs/LICENSE b/lib/rs/LICENSE new file mode 120000 index 00000000000..30cff7403da --- /dev/null +++ b/lib/rs/LICENSE @@ -0,0 +1 @@ +../../LICENSE \ No newline at end of file diff --git a/lib/rs/Makefile.am b/lib/rs/Makefile.am index 7a9b30a4feb..307f8422877 100644 --- a/lib/rs/Makefile.am +++ b/lib/rs/Makefile.am @@ -45,10 +45,15 @@ clean-local: $(CARGO) clean -$(RM) Cargo.lock +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ src \ Cargo.toml \ README.md \ release.sh \ + NOTICE \ + LICENSE \ RELEASING.md diff --git a/lib/rs/NOTICE b/lib/rs/NOTICE new file mode 120000 index 00000000000..fb376cfaa47 --- /dev/null +++ b/lib/rs/NOTICE @@ -0,0 +1 @@ +../../NOTICE \ No newline at end of file diff --git a/lib/rs/src/lib.rs b/lib/rs/src/lib.rs index 84c1f9b71a7..2f6018810b3 100644 --- a/lib/rs/src/lib.rs +++ b/lib/rs/src/lib.rs @@ -53,7 +53,7 @@ //! [tutorial]: https://github.com/apache/thrift/tree/master/tutorial/rs #![crate_type = "lib"] -#![doc(test(attr(allow(unused_variables), deny(warnings))))] +#![doc(test(attr(allow(unused_variables, dead_code), deny(warnings))))] #![deny(bare_trait_objects)] // NOTE: this macro has to be defined before any modules. See: diff --git a/lib/rs/src/protocol/compact.rs b/lib/rs/src/protocol/compact.rs index c0c43722ed8..4dc45cac2fd 100644 --- a/lib/rs/src/protocol/compact.rs +++ b/lib/rs/src/protocol/compact.rs @@ -210,6 +210,10 @@ where None => { let b = self.read_byte()?; match b { + // Previous versions of the thrift compact protocol specification said to use 0 + // and 1 inside collections, but that differed from existing implementations. + // The specification was updated in https://github.com/apache/thrift/commit/2c29c5665bc442e703480bb0ee60fe925ffe02e8. + 0x00 => Ok(false), 0x01 => Ok(true), 0x02 => Ok(false), unkn => Err(crate::Error::Protocol(crate::ProtocolError { @@ -652,7 +656,11 @@ fn type_to_u8(field_type: TType) -> u8 { fn collection_u8_to_type(b: u8) -> crate::Result { match b { - 0x01 => Ok(TType::Bool), + // For historical and compatibility reasons, a reader should be capable to deal with both cases. + // The only valid value in the original spec was 2, but due to a widespread implementation bug + // the defacto standard across large parts of the library became 1 instead. + // As a result, both values are now allowed. + 0x01 | 0x02 => Ok(TType::Bool), o => u8_to_type(o), } } @@ -681,8 +689,6 @@ fn u8_to_type(b: u8) -> crate::Result { #[cfg(test)] mod tests { - use std::i32; - use crate::protocol::{ TFieldIdentifier, TInputProtocol, TListIdentifier, TMapIdentifier, TMessageIdentifier, TMessageType, TOutputProtocol, TSetIdentifier, TStructIdentifier, TType, @@ -2818,7 +2824,7 @@ mod tests { copy_write_buffer_to_read_buffer!(o_prot); let read_double = i_prot.read_double().unwrap(); - assert!(read_double - double < std::f64::EPSILON); + assert!((read_double - double).abs() < f64::EPSILON); } #[test] @@ -2841,4 +2847,40 @@ mod tests { assert!(write_fn(&mut o_prot).is_ok()); assert_eq!(o_prot.transport.write_bytes().len(), 0); } + + #[test] + fn must_read_boolean_list() { + let (mut i_prot, _) = test_objects(); + + let source_bytes: [u8; 3] = [0x21, 2, 1]; + + i_prot.transport.set_readable_bytes(&source_bytes); + + let (ttype, element_count) = assert_success!(i_prot.read_list_set_begin()); + + assert_eq!(ttype, TType::Bool); + assert_eq!(element_count, 2); + assert_eq!(i_prot.read_bool().unwrap(), false); + assert_eq!(i_prot.read_bool().unwrap(), true); + + assert_success!(i_prot.read_list_end()); + } + + #[test] + fn must_read_boolean_list_alternative_encoding() { + let (mut i_prot, _) = test_objects(); + + let source_bytes: [u8; 3] = [0x22, 0, 1]; + + i_prot.transport.set_readable_bytes(&source_bytes); + + let (ttype, element_count) = assert_success!(i_prot.read_list_set_begin()); + + assert_eq!(ttype, TType::Bool); + assert_eq!(element_count, 2); + assert_eq!(i_prot.read_bool().unwrap(), false); + assert_eq!(i_prot.read_bool().unwrap(), true); + + assert_success!(i_prot.read_list_end()); + } } diff --git a/lib/rs/src/protocol/stored.rs b/lib/rs/src/protocol/stored.rs index f4bdfb19780..04d3277faf3 100644 --- a/lib/rs/src/protocol/stored.rs +++ b/lib/rs/src/protocol/stored.rs @@ -83,6 +83,8 @@ pub struct TStoredInputProtocol<'a> { message_ident: Option, } +// Erroneous suggestion by clippy +#[allow(clippy::needless_lifetimes)] impl<'a> TStoredInputProtocol<'a> { /// Create a `TStoredInputProtocol` that delegates all calls other than /// `TInputProtocol::read_message_begin(...)` to a `wrapped` @@ -100,6 +102,8 @@ impl<'a> TStoredInputProtocol<'a> { } } +// Erroneous suggestion by clippy +#[allow(clippy::needless_lifetimes)] impl<'a> TInputProtocol for TStoredInputProtocol<'a> { fn read_message_begin(&mut self) -> crate::Result { self.message_ident.take().ok_or_else(|| { diff --git a/lib/rs/src/transport/framed.rs b/lib/rs/src/transport/framed.rs index c30ccd9ed62..d8a7448725f 100644 --- a/lib/rs/src/transport/framed.rs +++ b/lib/rs/src/transport/framed.rs @@ -97,7 +97,7 @@ where self.buf.resize(buf_capacity, 0); self.chan.read_exact(&mut self.buf[..message_size])?; - self.cap = message_size as usize; + self.cap = message_size; self.pos = 0; } diff --git a/lib/rs/test/Makefile.am b/lib/rs/test/Makefile.am index 017a2c4672f..73fe156cc5f 100644 --- a/lib/rs/test/Makefile.am +++ b/lib/rs/test/Makefile.am @@ -47,6 +47,9 @@ clean-local: -$(RM) src/identifiers.rs -$(RM) -r bin +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ Cargo.toml \ thrifts/Base_One.thrift \ diff --git a/lib/rs/test_recursive/Makefile.am b/lib/rs/test_recursive/Makefile.am index e676ccdca10..ec7d4fc413b 100644 --- a/lib/rs/test_recursive/Makefile.am +++ b/lib/rs/test_recursive/Makefile.am @@ -29,5 +29,8 @@ clean-local: $(CARGO) clean -$(RM) Cargo.lock +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ Cargo.toml diff --git a/lib/rs/test_recursive/src/Makefile.am b/lib/rs/test_recursive/src/Makefile.am index 4bfd557d00c..eeb81abc7ad 100644 --- a/lib/rs/test_recursive/src/Makefile.am +++ b/lib/rs/test_recursive/src/Makefile.am @@ -29,6 +29,9 @@ check: stubs clean-local: -$(RM) vehicles.rs +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ lib.rs \ Vehicles.thrift diff --git a/lib/rs/test_recursive/src/maintenance/Makefile.am b/lib/rs/test_recursive/src/maintenance/Makefile.am index e2526bdc984..a1f0ae8f228 100644 --- a/lib/rs/test_recursive/src/maintenance/Makefile.am +++ b/lib/rs/test_recursive/src/maintenance/Makefile.am @@ -29,6 +29,9 @@ check: stubs clean-local: -$(RM) maintenance_facility.rs +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ mod.rs \ MaintenanceFacility.thrift diff --git a/lib/rs/test_recursive/src/transit/Makefile.am b/lib/rs/test_recursive/src/transit/Makefile.am index 908becb25bf..217227a0e5d 100644 --- a/lib/rs/test_recursive/src/transit/Makefile.am +++ b/lib/rs/test_recursive/src/transit/Makefile.am @@ -34,6 +34,9 @@ clean-local: -$(RM) trains.rs -$(RM) transporters.rs +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ mod.rs \ Buses.thrift \ diff --git a/lib/rs/test_recursive/src/transit/light/Makefile.am b/lib/rs/test_recursive/src/transit/light/Makefile.am index 88fd5310c37..b0e3c76a32d 100644 --- a/lib/rs/test_recursive/src/transit/light/Makefile.am +++ b/lib/rs/test_recursive/src/transit/light/Makefile.am @@ -31,6 +31,9 @@ clean-local: -$(RM) light_rail.rs -$(RM) streetcars.rs +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ mod.rs \ LightRail.thrift \ diff --git a/lib/rs/test_recursive/src/transit/services/Makefile.am b/lib/rs/test_recursive/src/transit/services/Makefile.am index 12e9e293515..a141c6dd558 100644 --- a/lib/rs/test_recursive/src/transit/services/Makefile.am +++ b/lib/rs/test_recursive/src/transit/services/Makefile.am @@ -29,6 +29,9 @@ check: stubs clean-local: -$(RM) city_services.rs +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ mod.rs \ CityServices.thrift diff --git a/lib/st/package.xml b/lib/st/package.xml index 7af883ee624..5f92da86515 100644 --- a/lib/st/package.xml +++ b/lib/st/package.xml @@ -17,7 +17,7 @@ specific language governing permissions and limitations under the License. --> - + libthrift-st thrift.st diff --git a/lib/swift/Makefile.am b/lib/swift/Makefile.am index 6a6644ac01b..ac61716d6dc 100644 --- a/lib/swift/Makefile.am +++ b/lib/swift/Makefile.am @@ -35,6 +35,9 @@ precross: check-local: swift test +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ Package.swift \ Sources \ diff --git a/lib/swift/Sources/LinuxHelper.swift b/lib/swift/Sources/LinuxHelper.swift index 83603f87996..7ab0b3e7964 100644 --- a/lib/swift/Sources/LinuxHelper.swift +++ b/lib/swift/Sources/LinuxHelper.swift @@ -27,7 +27,7 @@ import CoreFoundation extension UInt { public static func &(lhs: UInt, rhs: Int) -> UInt { - let cast = unsafeBitCast(rhs, to: UInt.self) + let cast = UInt(bitPattern: rhs) return lhs & cast } } diff --git a/lib/swift/Sources/TSocketServer.swift b/lib/swift/Sources/TSocketServer.swift index 6cd9adfe41c..27b4b5521f1 100644 --- a/lib/swift/Sources/TSocketServer.swift +++ b/lib/swift/Sources/TSocketServer.swift @@ -102,6 +102,49 @@ open class TSocketServer Int32 { + let socketAddressCasted = withUnsafePointer(to: &socketAddress) { + $0.withMemoryRebound(to: sockaddr.self, capacity: 1) { + return $0 + } + } + return Sys.connect(fd, socketAddressCasted, socklen_t(MemoryLayout.size(ofValue: socketAddress))) + } + public func bind() -> Int32 { + let socketAddressCasted = withUnsafePointer(to: &socketAddress) { + $0.withMemoryRebound(to: sockaddr.self, capacity: 1) { + return $0 + } + } + return Sys.bind(fd, socketAddressCasted, socklen_t(MemoryLayout.size(ofValue: socketAddress))) + } +} diff --git a/lib/swift/Tests/ThriftTests/ThriftTests.swift b/lib/swift/Tests/ThriftTests/ThriftTests.swift index 3c6854c6587..2632cc3e3bf 100644 --- a/lib/swift/Tests/ThriftTests/ThriftTests.swift +++ b/lib/swift/Tests/ThriftTests/ThriftTests.swift @@ -3,7 +3,7 @@ import XCTest class ThriftTests: XCTestCase { func testVersion() { - XCTAssertEqual(Thrift().version, "0.20.0") + XCTAssertEqual(Thrift().version, "0.22.0") } static var allTests : [(String, (ThriftTests) -> () throws -> Void)] { diff --git a/lib/ts/Gruntfile.js b/lib/ts/Gruntfile.js index 61ab582741d..3e4b1c49227 100644 --- a/lib/ts/Gruntfile.js +++ b/lib/ts/Gruntfile.js @@ -5,55 +5,57 @@ // 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'; +module.exports = function (grunt) { + "use strict"; grunt.initConfig({ - pkg: grunt.file.readJSON('package.json'), + pkg: grunt.file.readJSON("package.json"), concat: { options: { - separator: ';' + separator: ";", }, dist: { - src: ['src/**/*.js'], - dest: 'dist/<%= pkg.name %>.js' - } + 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' + command: + "mkdir -p test/build/ts/lib; cp ../js/src/thrift.js test/build/ts/thrift.js", }, InstallThriftNodeJSDep: { - command: 'cd ../..; npm install' + command: "cd ../..; npm install", }, InstallTestLibs: { - command: 'cd test; ant download_jslibs' + command: "cd test; ant download_jslibs", }, ThriftGen: { command: [ - 'mkdir -p test/gen-js', - '../../compiler/cpp/thrift -gen js:ts --out test/gen-js ../../test/v0.16/ThriftTest.thrift', - 'mkdir -p test/gen-nodejs', - '../../compiler/cpp/thrift -gen js:node,ts --out test/gen-nodejs ../../test/v0.16/ThriftTest.thrift', - ].join(' && ') + "mkdir -p test/gen-js", + "../../compiler/cpp/thrift -gen js:ts --out test/gen-js ../../test/v0.16/ThriftTest.thrift", + "mkdir -p test/gen-nodejs", + "../../compiler/cpp/thrift -gen js:node,ts --out test/gen-nodejs ../../test/v0.16/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(' && ') + "./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' + 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"} - } + env: { NODE_PATH: "../../nodejs/lib:../../../node_modules" }, + }, }, command: "node server_http.js", }, @@ -61,103 +63,104 @@ module.exports = function(grunt) { options: { execOptions: { cwd: "./test", - } + }, }, - command : "../node_modules/typescript/bin/tsc --listFiles --outDir build/ts" + 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(" && ") + ].join(" && "), }, InstallGeneratedCode: { command: [ "mkdir -p test/build/ts", - "cp -r test/gen-js test/build/ts" - ].join(" && ") + "cp -r test/gen-js test/build/ts", + ].join(" && "), }, }, qunit: { ThriftJS: { options: { - urls: [ - 'http://localhost:8089/test.html' - ], + urls: ["http://localhost:8089/test.html"], puppeteer: { headless: true, - args: ['--no-sandbox'], + args: ["--no-sandbox"], }, - } + }, }, ThriftJS_Int64: { options: { - urls: [ - 'http://localhost:8089/test-int64.html' - ], + urls: ["http://localhost:8089/test-int64.html"], puppeteer: { headless: true, - args: ['--no-sandbox'], + args: ["--no-sandbox"], ignoreHTTPSErrors: true, }, - } + }, }, }, jshint: { // The main Thrift library file. not es6 yet :( lib: { - src: ['../js/src/**/*.js'], + src: ["../js/src/**/*.js"], }, // The test files use es6 test: { - src: ['Gruntfile.js', 'test/*.js'], + src: ["Gruntfile.js", "test/*.js"], options: { esversion: 6, - } + }, }, gen_js_code: { - src: ['test/gen-js/*.js'], + src: ["test/gen-js/*.js"], }, gen_node_code: { - src: ['test/gen-nodejs/*.js'], + src: ["test/gen-nodejs/*.js"], options: { node: true, - } + }, }, }, }); - grunt.loadNpmTasks('grunt-contrib-jshint'); - grunt.loadNpmTasks('grunt-contrib-qunit'); - grunt.loadNpmTasks('grunt-shell-spawn'); + 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( + "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("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("test", [ + "installAndGenerate", + "jshint", + "shell:ThriftTestServer", + "wait", + "qunit:ThriftJS", + "qunit:ThriftJS_Int64", + "shell:ThriftTestServer:kill", ]); - grunt.registerTask('default', ['test']); + grunt.registerTask("default", ["test"]); }; diff --git a/lib/ts/Makefile.am b/lib/ts/Makefile.am index 62ea2069f16..05d71e4d364 100644 --- a/lib/ts/Makefile.am +++ b/lib/ts/Makefile.am @@ -48,6 +48,9 @@ dist-hook: $(RM) -r $(distdir)/test/build/ $(RM) -r $(distdir)/test/gen-*/ +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ coding_standards.md \ Gruntfile.js \ diff --git a/lib/ts/package-lock.json b/lib/ts/package-lock.json index f99d8a34713..97400009484 100644 --- a/lib/ts/package-lock.json +++ b/lib/ts/package-lock.json @@ -1,12 +1,12 @@ { "name": "thrift", - "version": "0.20.0", + "version": "0.22.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "thrift", - "version": "0.20.0", + "version": "0.22.0", "license": "Apache-2.0", "dependencies": { "bufferutil": "^4.0.1", @@ -31,7 +31,7 @@ "jslint": "^0.12.0", "node-int64": "^0.4.0", "phantom": "^6.0.3", - "typescript": "^3.2.4" + "typescript": "^5.7.2" } }, "node_modules/@babel/parser": { @@ -85,10 +85,13 @@ "integrity": "sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==" }, "node_modules/@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 + "version": "22.10.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.5.tgz", + "integrity": "sha512-F8Q+SeGimwOo86fiovQh8qiXfFEh2/ocYv7tU5pJ3EXMSSxk1Joj5wefpFK2fHTf/N6HKGSxIDBT9f3gCxXPkQ==", + "dev": true, + "dependencies": { + "undici-types": "~6.20.0" + } }, "node_modules/@types/node-int64": { "version": "0.4.29", @@ -427,12 +430,12 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -1270,10 +1273,11 @@ } }, "node_modules/elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "version": "6.6.1", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.6.1.tgz", + "integrity": "sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==", "dev": true, + "license": "MIT", "dependencies": { "bn.js": "^4.11.9", "brorand": "^1.1.0", @@ -1465,9 +1469,9 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "dependencies": { "to-regex-range": "^5.0.1" @@ -4630,16 +4634,16 @@ "dev": true }, "node_modules/typescript": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.2.4.tgz", - "integrity": "sha512-0RNDbSdEokBeEAkgNbxJ+BLwSManFy9TeXz8uW+48j/xhEXv1ePME60olyzw2XzUqUBNAYFeJadIqAgNqIACwg==", + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", + "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { - "node": ">=4.2.0" + "node": ">=14.17" } }, "node_modules/uc.micro": { @@ -4728,6 +4732,12 @@ "node": "*" } }, + "node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "dev": true + }, "node_modules/uri-js": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", @@ -4951,9 +4961,9 @@ "dev": true }, "node_modules/ws": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", - "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.3.tgz", + "integrity": "sha512-jmTjYU0j60B+vHey6TfR3Z7RD61z/hmxBS3VMSGIrroOWXQEneK1zNuotOUrGyBHQj0yrpsLHPWtigEFd13ndA==", "dev": true, "dependencies": { "async-limiter": "~1.0.0" diff --git a/lib/ts/package.json b/lib/ts/package.json index 054807f91c9..17988c6a4a0 100644 --- a/lib/ts/package.json +++ b/lib/ts/package.json @@ -1,6 +1,6 @@ { "name": "thrift", - "version": "0.20.0", + "version": "0.22.0", "description": "Thrift is a software framework for scalable cross-language services development.", "author": { "name": "Apache Thrift Developers", @@ -27,7 +27,7 @@ "jslint": "^0.12.0", "node-int64": "^0.4.0", "phantom": "^6.0.3", - "typescript": "^3.2.4" + "typescript": "^5.7.2" }, "dependencies": { "bufferutil": "^4.0.1", diff --git a/lib/ts/test/phantom-client.ts b/lib/ts/test/phantom-client.ts index 55189372536..90a532d6ff8 100644 --- a/lib/ts/test/phantom-client.ts +++ b/lib/ts/test/phantom-client.ts @@ -16,337 +16,360 @@ * specific language governing permissions and limitations * under the License. */ - /* jshint -W100 */ +/* 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'); +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 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; + 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; } - 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 hit = false; + for (var k in keys) { + if (arg.slice(0, k.length) === k) { + opts[keys[k]] = arg.slice(k.length); + hit = true; + break; } } - var portAsInt: number = parseInt(opts.port, 10); - if (!opts.port || portAsInt < 1 || portAsInt > 65535) { - throw new Error('Invalid port number'); + if (!hit) { + throw new Error("Unknown argument: " + arg); } - 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]); - } + } + 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"); + } + + 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], + ); } - }); - - 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) + } + + 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; + string_thing: "Hello2", + byte_thing: 2, + i32_thing: 2, + i64_thing: new Int64(2), + }, + ], }; - - 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 + 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); + } +})(); diff --git a/lib/ts/test/server_http.js b/lib/ts/test/server_http.js index 8380c3a7732..662a0a7b313 100644 --- a/lib/ts/test/server_http.js +++ b/lib/ts/test/server_http.js @@ -28,28 +28,30 @@ // 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 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 ThriftTestHandler = require("./test_handler").ThriftTestHandler; const ThriftTestSvcOpt = { - transport: thrift.TBufferedTransport, - protocol: thrift.TJSONProtocol, - processor: ThriftTestSvc, - handler: ThriftTestHandler + transport: thrift.TBufferedTransport, + protocol: thrift.TJSONProtocol, + processor: ThriftTestSvc, + handler: ThriftTestHandler, }; const ThriftWebServerOptions = { - files: __dirname, - services: { - '/service': ThriftTestSvcOpt - } + 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}`); +console.log( + `Http/Thrift Server (ES6 mode ${es6Mode}) running on port: ${port}`, +); diff --git a/lib/ts/test/test-int64.ts b/lib/ts/test/test-int64.ts index 254d8d7bfcc..10e5946fc96 100644 --- a/lib/ts/test/test-int64.ts +++ b/lib/ts/test/test-int64.ts @@ -16,86 +16,90 @@ * specific language governing permissions and limitations * under the License. */ - /* jshint -W100 */ +/* 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') { +if (typeof QUnit.log == "function") { // When using real QUnit (fron PhantomJS) log failures to console - QUnit.log(function(details) { + QUnit.log(function (details) { if (!details.result) { - console.log('======== FAIL ========'); - console.log('TestName: ' + details.name); + 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('======================'); + 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() - ); +QUnit.module("Int64"); - for (let i = 0; i < EXPECTED_INT64_LIST.length; ++i) { - assert.ok(EXPECTED_INT64_LIST[i].equals(Int64Test.INT64_LIST[i])); - } +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){ - let int64Object = EXPECTED_INT64_LIST[i]; - assert.ok(Int64Test.INT64_2_INT64_MAP[JSONInt64.toDecimalString(int64Object)].equals(int64Object)); - } + for (let i = 0; i < EXPECTED_INT64_LIST.length; ++i) { + assert.ok(EXPECTED_INT64_LIST[i].equals(Int64Test.INT64_LIST[i])); + } - console.log('Int64 test -- ends'); - }); + 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.ts b/lib/ts/test/test.ts index 31fdcbff8bc..614461dc1fc 100644 --- a/lib/ts/test/test.ts +++ b/lib/ts/test/test.ts @@ -7,336 +7,365 @@ 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 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'); +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('======================'); - } - }); +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ú, 粵語"; - +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]); - } - } + 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); - }); - +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(); - }); - }); +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 index 8ba296ba108..825c5675c8c 100644 --- a/lib/ts/test/test_handler.js +++ b/lib/ts/test/test_handler.js @@ -20,87 +20,87 @@ //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 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'); +const TException = require("../../nodejs/lib/thrift").TException; +const Int64 = require("node-int64"); exports.ThriftTestHandler = { - testVoid: function(result) { - console.log('testVoid()'); + testVoid: function (result) { + console.log("testVoid()"); result(null); }, - testString: function(thing, result) { - console.log('testString(\'' + thing + '\')'); + testString: function (thing, result) { + console.log("testString('" + thing + "')"); result(null, thing); }, - testByte: function(thing, result) { - console.log('testByte(' + thing + ')'); + testByte: function (thing, result) { + console.log("testByte(" + thing + ")"); result(null, thing); }, - testI32: function(thing, result) { - console.log('testI32(' + thing + ')'); + testI32: function (thing, result) { + console.log("testI32(" + thing + ")"); result(null, thing); }, - testI64: function(thing, result) { - console.log('testI64(' + thing + ')'); + testI64: function (thing, result) { + console.log("testI64(" + thing + ")"); result(null, thing); }, - testDouble: function(thing, result) { - console.log('testDouble(' + thing + ')'); + testDouble: function (thing, result) { + console.log("testDouble(" + thing + ")"); result(null, thing); }, - testBinary: function(thing, result) { - console.log('testBinary(\'' + thing + '\')'); + testBinary: function (thing, result) { + console.log("testBinary('" + thing + "')"); result(null, thing); }, - testStruct: function(thing, result) { - console.log('testStruct('); + testStruct: function (thing, result) { + console.log("testStruct("); console.log(thing); - console.log(')'); + console.log(")"); result(null, thing); }, - testNest: function(nest, result) { - console.log('testNest('); + testNest: function (nest, result) { + console.log("testNest("); console.log(nest); - console.log(')'); + console.log(")"); result(null, nest); }, - testMap: function(thing, result) { - console.log('testMap('); + testMap: function (thing, result) { + console.log("testMap("); console.log(thing); - console.log(')'); + console.log(")"); result(null, thing); }, - testStringMap: function(thing, result) { - console.log('testStringMap('); + testStringMap: function (thing, result) { + console.log("testStringMap("); console.log(thing); - console.log(')'); + console.log(")"); result(null, thing); }, - testSet: function(thing, result) { - console.log('testSet('); + testSet: function (thing, result) { + console.log("testSet("); console.log(thing); - console.log(')'); + console.log(")"); result(null, thing); }, - testList: function(thing, result) { - console.log('testList('); + testList: function (thing, result) { + console.log("testList("); console.log(thing); - console.log(')'); + console.log(")"); result(null, thing); }, - testEnum: function(thing, result) { - console.log('testEnum(' + thing + ')'); + testEnum: function (thing, result) { + console.log("testEnum(" + thing + ")"); result(null, thing); }, - testTypedef: function(thing, result) { - console.log('testTypedef(' + thing + ')'); + testTypedef: function (thing, result) { + console.log("testTypedef(" + thing + ")"); result(null, thing); }, - testMapMap: function(hello, result) { - console.log('testMapMap(' + hello + ')'); + testMapMap: function (hello, result) { + console.log("testMapMap(" + hello + ")"); const mapmap = []; const pos = []; @@ -114,19 +114,19 @@ exports.ThriftTestHandler = { result(null, mapmap); }, - testInsanity: function(argument, result) { - console.log('testInsanity('); + testInsanity: function (argument, result) { + console.log("testInsanity("); console.log(argument); - console.log(')'); + console.log(")"); const hello = new ttypes.Xtruct(); - hello.string_thing = 'Hello2'; + 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.string_thing = "Goodbye4"; goodbye.byte_thing = 4; goodbye.i32_thing = 4; goodbye.i64_thing = new Int64(4); @@ -150,45 +150,45 @@ exports.ThriftTestHandler = { insane[1] = first_map; insane[2] = second_map; - console.log('insane result:'); + console.log("insane result:"); console.log(insane); result(null, insane); }, - testMulti: function(arg0, arg1, arg2, arg3, arg4, arg5, result) { - console.log('testMulti()'); + testMulti: function (arg0, arg1, arg2, arg3, arg4, arg5, result) { + console.log("testMulti()"); const hello = new ttypes.Xtruct(); - hello.string_thing = 'Hello2'; + 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') { + 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') { + } else if (arg === "TException") { result(new TException(arg)); } else { result(null); } }, - testMultiException: function(arg0, arg1, result) { - console.log('testMultiException(' + arg0 + ', ' + arg1 + ')'); - if (arg0 === ('Xception')) { + 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'; + x.message = "This is an Xception"; result(x); - } else if (arg0 === ('Xception2')) { + } 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'; + x2.struct_thing.string_thing = "This is an Xception2"; result(x2); } @@ -196,7 +196,9 @@ exports.ThriftTestHandler = { res.string_thing = arg1; result(null, res); }, - testOneway: function(sleepFor, result) { - console.log('testOneway(' + sleepFor + ') => JavaScript (like Rust) never sleeps!'); - } -}; //ThriftTestSvcHandler + testOneway: function (sleepFor, result) { + console.log( + "testOneway(" + sleepFor + ") => JavaScript (like Rust) never sleeps!", + ); + }, +}; //ThriftTestSvcHandler diff --git a/lib/ts/thrift.d.ts b/lib/ts/thrift.d.ts index 0ba46c91497..8e9d565fab5 100644 --- a/lib/ts/thrift.d.ts +++ b/lib/ts/thrift.d.ts @@ -29,7 +29,7 @@ declare module Thrift { * @property {number} VOID - No value (only legal for return types). * @property {number} BOOL - True/False integer. * @property {number} BYTE - Signed 8 bit integer. - * @property {number} I08 - Signed 8 bit integer. + * @property {number} I08 - Signed 8 bit integer. * @property {number} DOUBLE - 64 bit IEEE 854 floating point. * @property {number} I16 - Signed 16 bit integer. * @property {number} I32 - Signed 32 bit integer. @@ -44,23 +44,23 @@ declare module Thrift { * @property {number} UTF16 - Array of bytes representing a string of UTF16 encoded characters. */ interface Type { - 'STOP': number; - 'VOID': number; - 'BOOL': number; - 'BYTE': number; - 'I08': number; - 'DOUBLE': number; - 'I16': number; - 'I32': number; - 'I64': number; - 'STRING': number; - 'UTF7': number; - 'STRUCT': number; - 'MAP': number; - 'SET': number; - 'LIST': number; - 'UTF8': number; - 'UTF16': number; + STOP: number; + VOID: number; + BOOL: number; + BYTE: number; + I08: number; + DOUBLE: number; + I16: number; + I32: number; + I64: number; + STRING: number; + UTF7: number; + STRUCT: number; + MAP: number; + SET: number; + LIST: number; + UTF8: number; + UTF16: number; } var Type: Type; @@ -72,10 +72,10 @@ declare module Thrift { * @property {number} ONEWAY - Oneway RPC call from client to server with no response. */ interface MessageType { - 'CALL': number; - 'REPLY': number; - 'EXCEPTION': number; - 'ONEWAY': number; + CALL: number; + REPLY: number; + EXCEPTION: number; + ONEWAY: number; } var MessageType: MessageType; @@ -92,7 +92,11 @@ declare module Thrift { * @param {function} superConstructor - Contstructor function to set as base. * @param {string} [name] - Type name to set as name property in derived prototype. */ - function inherits(constructor: Function, superConstructor: Function, name?: string): void; + function inherits( + constructor: Function, + superConstructor: Function, + name?: string, + ): void; /** * TException is the base class for all Thrift exceptions types. @@ -129,17 +133,17 @@ declare module Thrift { * @property {number} UNSUPPORTED_CLIENT_TYPE - Unused. */ interface TApplicationExceptionType { - 'UNKNOWN': number; - 'UNKNOWN_METHOD': number; - 'INVALID_MESSAGE_TYPE': number; - 'WRONG_METHOD_NAME': number; - 'BAD_SEQUENCE_ID': number; - 'MISSING_RESULT': number; - 'INTERNAL_ERROR': number; - 'PROTOCOL_ERROR': number; - 'INVALID_TRANSFORM': number; - 'INVALID_PROTOCOL': number; - 'UNSUPPORTED_CLIENT_TYPE': number; + UNKNOWN: number; + UNKNOWN_METHOD: number; + INVALID_MESSAGE_TYPE: number; + WRONG_METHOD_NAME: number; + BAD_SEQUENCE_ID: number; + MISSING_RESULT: number; + INTERNAL_ERROR: number; + PROTOCOL_ERROR: number; + INVALID_TRANSFORM: number; + INVALID_PROTOCOL: number; + UNSUPPORTED_CLIENT_TYPE: number; } var TApplicationExceptionType: TApplicationExceptionType; @@ -179,7 +183,7 @@ declare module Thrift { /** * The Apache Thrift Transport layer performs byte level I/O between RPC * clients and servers. The JavaScript Transport object type uses Http[s]/XHR and is - * the sole browser based Thrift transport. Target servers must implement the http[s] + * the sole browser based Thrift transport. Target servers must implement the http[s] * transport (see: node.js example server). */ class TXHRTransport { @@ -208,7 +212,7 @@ declare module Thrift { /** * Sends the current XRH request if the transport was created with a URL and * the async parameter if false. If the transport was not created with a URL - * or the async parameter is True or the URL is an empty string, the current + * or the async parameter is True or the URL is an empty string, the current * send buffer is returned. * @param {object} async - If true the current send buffer is returned. * @param {function} callback - Optional async completion callback. @@ -224,7 +228,12 @@ declare module Thrift { * @param {function} recv_method - The Thrift Service Client receive method for the call. * @returns {object} A new jQuery XHR object. */ - jqRequest(client: Object, postData: any, args: Function, recv_method: Function): Object; + jqRequest( + client: Object, + postData: any, + args: Function, + recv_method: Function, + ): Object; /** * Sets the buffer to use when receiving server responses. @@ -281,22 +290,22 @@ declare module Thrift { /** * Old alias of the TXHRTransport for backwards compatibility. */ - class Transport extends TXHRTransport { } + class Transport extends TXHRTransport {} /** - * The Apache Thrift Transport layer performs byte level I/O - * between RPC clients and servers. The JavaScript TWebSocketTransport object + * The Apache Thrift Transport layer performs byte level I/O + * between RPC clients and servers. The JavaScript TWebSocketTransport object * uses the WebSocket protocol. Target servers must implement WebSocket. */ class TWebSocketTransport { - url: string; //Where to connect - socket: any; //The web socket + url: string; //Where to connect + socket: any; //The web socket callbacks: Function[]; //Pending callbacks - send_pending: any[]; //Buffers/Callback pairs waiting to be sent - send_buf: string; //Outbound data, immutable until sent - recv_buf: string; //Inbound data - rb_wpos: number; //Network write position in receive buffer - rb_rpos: number; //Client read position in receive buffer + send_pending: any[]; //Buffers/Callback pairs waiting to be sent + send_buf: string; //Outbound data, immutable until sent + recv_buf: string; //Inbound data + rb_wpos: number; //Network write position in receive buffer + rb_rpos: number; //Client read position in receive buffer /** * Constructor Function for the WebSocket transport. @@ -307,12 +316,12 @@ declare module Thrift { __reset(url: string): void; /** - * Sends the current WS request and registers callback. The async - * parameter is ignored (WS flush is always async) and the callback + * Sends the current WS request and registers callback. The async + * parameter is ignored (WS flush is always async) and the callback * function parameter is required. * @param {object} async - Ignored. * @param {function} callback - The client completion callback. - * @returns {undefined|string} Nothing (undefined) + * @returns {undefined|string} Nothing (undefined) */ flush(async: any, callback: Function): string; @@ -332,7 +341,7 @@ declare module Thrift { /** * Returns true if the transport is open - * @returns {boolean} + * @returns {boolean} */ isOpen(): boolean; @@ -374,8 +383,8 @@ declare module Thrift { } /** - * Apache Thrift Protocols perform serialization which enables cross - * language RPC. The Protocol type is the JavaScript browser implementation + * Apache Thrift Protocols perform serialization which enables cross + * language RPC. The Protocol type is the JavaScript browser implementation * of the Apache Thrift TJSONProtocol. */ class TJSONProtocol { @@ -401,17 +410,17 @@ declare module Thrift { /** * Thrift IDL type string to Id mapping. * The mapping table looks as follows: - * "tf" -> Thrift.Type.BOOL - * "i8" -> Thrift.Type.BYTE - * "i16" -> Thrift.Type.I16 - * "i32" -> Thrift.Type.I32 - * "i64" -> Thrift.Type.I64 + * "tf" -> Thrift.Type.BOOL + * "i8" -> Thrift.Type.BYTE + * "i16" -> Thrift.Type.I16 + * "i32" -> Thrift.Type.I32 + * "i64" -> Thrift.Type.I64 * "dbl" -> Thrift.Type.DOUBLE * "rec" -> Thrift.Type.STRUCT * "str" -> Thrift.Type.STRING - * "map" -> Thrift.Type.MAP - * "lst" -> Thrift.Type.LIST - * "set" -> Thrift.Type.SET + * "map" -> Thrift.Type.MAP + * "lst" -> Thrift.Type.LIST + * "set" -> Thrift.Type.SET */ RType: { [k: string]: number }; @@ -542,8 +551,8 @@ declare module Thrift { @property {Thrift.MessageType} mtype - The type of message call. @property {number} rseqid - The sequence number of the message (0 in Thrift RPC). */ - /** - * Deserializes the beginning of a message. + /** + * Deserializes the beginning of a message. * @returns {AnonReadMessageBeginReturn} */ readMessageBegin(): { fname: string; mtype: number; rseqid: number }; @@ -551,8 +560,8 @@ declare module Thrift { /** Deserializes the end of a message. */ readMessageEnd(): void; - /** - * Deserializes the beginning of a struct. + /** + * Deserializes the beginning of a struct. * @param {string} [name] - The name of the struct (ignored). * @returns {object} - An object with an empty string fname property. */ @@ -568,8 +577,8 @@ declare module Thrift { @property {Thrift.Type} ftype - The data type of the field. @property {number} fid - The unique identifier of the field. */ - /** - * Deserializes the beginning of a field. + /** + * Deserializes the beginning of a field. * @returns {AnonReadFieldBeginReturn} */ readFieldBegin(): { fname: string; ftype: number; fid: number }; @@ -584,8 +593,8 @@ declare module Thrift { @property {Thrift.Type} vtype - The data type of the value. @property {number} size - The number of elements in the map. */ - /** - * Deserializes the beginning of a map. + /** + * Deserializes the beginning of a map. * @returns {AnonReadMapBeginReturn} */ readMapBegin(): { ktype: number; vtype: number; size: number }; @@ -599,8 +608,8 @@ declare module Thrift { @property {Thrift.Type} etype - The data type of the element. @property {number} size - The number of elements in the collection. */ - /** - * Deserializes the beginning of a list. + /** + * Deserializes the beginning of a list. * @returns {AnonReadColBeginReturn} */ readListBegin(): { etype: number; size: number }; @@ -608,19 +617,22 @@ declare module Thrift { /** Deserializes the end of a list. */ readListEnd(): void; - /** - * Deserializes the beginning of a set. + /** + * Deserializes the beginning of a set. * @param {Thrift.Type} elemType - The data type of the elements (ignored). * @param {number} size - The number of elements in the list (ignored). * @returns {AnonReadColBeginReturn} */ - readSetBegin(elemType?: number, size?: number): { etype: number; size: number }; + readSetBegin( + elemType?: number, + size?: number, + ): { etype: number; size: number }; /** Deserializes the end of a set. */ readSetEnd(): void; - /** Returns an object with a value property set to - * False unless the next number in the protocol buffer + /** Returns an object with a value property set to + * False unless the next number in the protocol buffer * is 1, in which case the value property is True. */ readBool(): Object; @@ -652,7 +664,7 @@ declare module Thrift { next value found in the protocol buffer. */ readBinary(): Object; - /** + /** * Method to arbitrarily skip over data (not implemented). */ skip(type: number): void; @@ -661,7 +673,7 @@ declare module Thrift { /** * Old alias of the TXHRTransport for backwards compatibility. */ - class Protocol extends TJSONProtocol { } + class Protocol extends TJSONProtocol {} class MultiplexProtocol extends TJSONProtocol { serviceName: string; @@ -673,7 +685,12 @@ declare module Thrift { * @param {any} [strictRead] * @param {any} [strictWrite] */ - constructor(srvName: string, trans: Object, strictRead?: any, strictWrite?: any); + constructor( + srvName: string, + trans: Object, + strictRead?: any, + strictWrite?: any, + ); /** * Override writeMessageBegin method of prototype diff --git a/lib/xml/Makefile.am b/lib/xml/Makefile.am index bcad6bdd5af..6a1503a744f 100644 --- a/lib/xml/Makefile.am +++ b/lib/xml/Makefile.am @@ -24,6 +24,9 @@ if WITH_JAVA SUBDIRS += test endif +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ thrift-idl.xsd \ test diff --git a/lib/xml/test/Makefile.am b/lib/xml/test/Makefile.am index bb87a52038f..16bcfae383f 100644 --- a/lib/xml/test/Makefile.am +++ b/lib/xml/test/Makefile.am @@ -20,6 +20,9 @@ check: $(ANT) $(ANT_FLAGS) test +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + # Make sure this doesn't fail if ant is not configured. clean-local: ANT=$(ANT) ; if test -z "$$ANT" ; then ANT=: ; fi ; \ diff --git a/package-lock.json b/package-lock.json index 3f8780a5ab5..701dd076b71 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "thrift", - "version": "0.20.0", + "version": "0.22.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "thrift", - "version": "0.20.0", + "version": "0.22.0", "license": "Apache-2.0", "dependencies": { "browser-or-node": "^1.2.1", @@ -16,22 +16,24 @@ "ws": "^5.2.3" }, "devDependencies": { - "@types/node": "^10.12.6", + "@eslint/js": "^9.18.0", + "@types/node": "^22.10.5", "@types/node-int64": "^0.4.29", "@types/q": "^1.5.1", "buffer-equals": "^1.0.4", - "commander": "^2.14.1", + "commander": "^13.0.0", "connect": "^3.6.6", - "eslint": "^5.7.0", - "eslint-config-prettier": "^3.1.0", - "eslint-plugin-prettier": "^3.0.0", + "eslint": "^9.18.0", + "eslint-config-prettier": "^10.0.1", + "eslint-plugin-prettier": "^5.2.1", + "globals": "^15.14.0", "html-validator-cli": "^2.0.0", "jsdoc": "^4.0.2", "json-int64": "^1.0.2", "nyc": "^15.0.0", - "prettier": "^1.14.3", + "prettier": "^3.4.2", "tape": "^4.9.0", - "typescript": "^3.1.6", + "typescript": "^5.7.2", "utf-8-validate": "^5.0.0" }, "engines": { @@ -285,6 +287,15 @@ "ms": "^2.1.1" } }, + "node_modules/@babel/traverse/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/@babel/traverse/node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -305,6 +316,262 @@ "node": ">=6.9.0" } }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", + "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.1.tgz", + "integrity": "sha512-fo6Mtm5mWyKjA/Chy1BYTdn5mGJoDNjC7C64ug20ADsRDGrA85bN3uK3MaKbeRkRuuIEAR5N33Jr1pbm411/PA==", + "dev": true, + "dependencies": { + "@eslint/object-schema": "^2.1.5", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-array/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@eslint/config-array/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/@eslint/core": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.10.0.tgz", + "integrity": "sha512-gFHJ+xBOo4G3WRlR1e/3G8A6/KZAH6zcE/hkLRCZTi/B9avAG365QhFA8uOGzTMqgTghpn7/fSnscW++dpMSAw==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.2.0.tgz", + "integrity": "sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/@eslint/eslintrc/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@eslint/eslintrc/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/@eslint/js": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.18.0.tgz", + "integrity": "sha512-fK6L7rxcq6/z+AaQMtiFTkvbHkBLNlwyRxHpKawP0x3u9+NC6MQTnFW+AdpwC6gfHTW0051cokQgtTN2FqlxQA==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.5.tgz", + "integrity": "sha512-o0bhxnL89h5Bae5T318nFoFzGy+YE5i/gGkoPAgkmTVdRKTiv3p8JHevPiPaMwoloKfEiiaHlawCqaZMqRm+XQ==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.5.tgz", + "integrity": "sha512-lB05FkqEdUg2AA0xEbUz0SnkXT1LcCTa438W4IWTUh4hdOnVbQyOJ81OrDXsJk/LSiJHubgGEFoR5EHq1NsH1A==", + "dev": true, + "dependencies": { + "@eslint/core": "^0.10.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", + "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", + "dev": true, + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.3.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "dev": true, + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.1.tgz", + "integrity": "sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==", + "dev": true, + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.0.0.tgz", @@ -398,12 +665,36 @@ "node": ">=v12.0.0" } }, + "node_modules/@pkgr/core": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", + "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, "node_modules/@types/color-name": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", "dev": true }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true + }, "node_modules/@types/linkify-it": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.2.tgz", @@ -427,15 +718,18 @@ "dev": true }, "node_modules/@types/node": { - "version": "10.12.6", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.6.tgz", - "integrity": "sha512-+ZWB5Ec1iki99xQFzBlivlKxSZQ+fuUKBott8StBOnLN4dWbRHlgdg1XknpW6g0tweniN5DcOqA64CJyOUPSAw==", - "dev": true + "version": "22.10.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.5.tgz", + "integrity": "sha512-F8Q+SeGimwOo86fiovQh8qiXfFEh2/ocYv7tU5pJ3EXMSSxk1Joj5wefpFK2fHTf/N6HKGSxIDBT9f3gCxXPkQ==", + "dev": true, + "dependencies": { + "undici-types": "~6.20.0" + } }, "node_modules/@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==", + "version": "0.4.32", + "resolved": "https://registry.npmjs.org/@types/node-int64/-/node-int64-0.4.32.tgz", + "integrity": "sha512-xf/JsSlnXQ+mzvc0IpXemcrO4BrCfpgNpMco+GLcXkFk01k/gW9lGJu+Vof0ZSvHK6DsHJDPSbjFPs36QkWXqw==", "dev": true, "dependencies": { "@types/node": "*" @@ -448,9 +742,9 @@ "dev": true }, "node_modules/acorn": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", - "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -460,12 +754,12 @@ } }, "node_modules/acorn-jsx": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.0.tgz", - "integrity": "sha512-XkB50fn0MURDyww9+UYL3c1yLbOBz0ZFvrdYlGB8l+Ije1oSC75qAqrzSPjYQbdnQUzhlUGNKuesryAv0gxZOg==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, "peerDependencies": { - "acorn": "^6.0.0" + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "node_modules/aggregate-error": { @@ -497,30 +791,6 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/ajv/node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "node_modules/ansi-escapes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz", - "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/ansi-regex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", - "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", @@ -560,36 +830,6 @@ "sprintf-js": "~1.0.2" } }, - "node_modules/array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "dependencies": { - "array-uniq": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/asn1": { "version": "0.2.6", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", @@ -694,25 +934,13 @@ "node": ">=8" } }, - "node_modules/caller-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", - "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", - "dev": true, - "dependencies": { - "callsites": "^0.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/callsites": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", - "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=6" } }, "node_modules/camelcase": { @@ -756,19 +984,6 @@ "node": ">=4" } }, - "node_modules/chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true - }, - "node_modules/circular-json": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", - "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", - "deprecated": "CircularJSON is in maintenance only, flatted is its successor.", - "dev": true - }, "node_modules/clean-stack": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", @@ -778,24 +993,6 @@ "node": ">=6" } }, - "node_modules/cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", - "dev": true, - "dependencies": { - "restore-cursor": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/cli-width": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", - "dev": true - }, "node_modules/cliui": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", @@ -879,10 +1076,13 @@ } }, "node_modules/commander": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", - "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==", - "dev": true + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-13.0.0.tgz", + "integrity": "sha512-oPYleIY8wmTVzkvQq10AEok6YcTC4sRUBl8F9gVuwchGVUCTbl/vhLTaQqutuuySYOsu8YTgV+OxKc/8Yvx+mQ==", + "dev": true, + "engines": { + "node": ">=18" + } }, "node_modules/commondir": { "version": "1.0.1", @@ -927,19 +1127,17 @@ "dev": true }, "node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" }, "engines": { - "node": ">=4.8" + "node": ">= 8" } }, "node_modules/dashdash": { @@ -979,9 +1177,9 @@ "dev": true }, "node_modules/deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, "node_modules/default-require-extensions": { @@ -1014,24 +1212,6 @@ "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", "dev": true }, - "node_modules/del": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", - "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", - "dev": true, - "dependencies": { - "globby": "^5.0.0", - "is-path-cwd": "^1.0.0", - "is-path-in-cwd": "^1.0.0", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "rimraf": "^2.2.8" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -1041,18 +1221,6 @@ "node": ">=0.4.0" } }, - "node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", @@ -1145,159 +1313,315 @@ } }, "node_modules/eslint": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.7.0.tgz", - "integrity": "sha512-zYCeFQahsxffGl87U2aJ7DPyH8CbWgxBC213Y8+TCanhUTf2gEvfq3EKpHmEcozTLyPmGe9LZdMAwC/CpJBM5A==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "ajv": "^6.5.3", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", - "debug": "^4.0.1", - "doctrine": "^2.1.0", - "eslint-scope": "^4.0.0", - "eslint-utils": "^1.3.1", - "eslint-visitor-keys": "^1.0.0", - "espree": "^4.0.0", - "esquery": "^1.0.1", + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.18.0.tgz", + "integrity": "sha512-+waTfRWQlSbpt3KWE+CjrPPYnbq9kfZIYUqapc0uBXyjTp8aYXZDsUH16m39Ryq3NjAVP4tjuF7KaukeqoCoaA==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.19.0", + "@eslint/core": "^0.10.0", + "@eslint/eslintrc": "^3.2.0", + "@eslint/js": "9.18.0", + "@eslint/plugin-kit": "^0.2.5", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.1", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.2.0", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0", + "esquery": "^1.5.0", "esutils": "^2.0.2", - "file-entry-cache": "^2.0.0", - "functional-red-black-tree": "^1.0.1", - "glob": "^7.1.2", - "globals": "^11.7.0", - "ignore": "^4.0.6", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", "imurmurhash": "^0.1.4", - "inquirer": "^6.1.0", - "is-resolvable": "^1.1.0", - "js-yaml": "^3.12.0", + "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.5", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.8.2", - "path-is-inside": "^1.0.2", - "pluralize": "^7.0.0", - "progress": "^2.0.0", - "regexpp": "^2.0.1", - "require-uncached": "^1.0.3", - "semver": "^5.5.1", - "strip-ansi": "^4.0.0", - "strip-json-comments": "^2.0.1", - "table": "^5.0.2", - "text-table": "^0.2.0" + "optionator": "^0.9.3" }, "bin": { "eslint": "bin/eslint.js" }, "engines": { - "node": "^6.14.0 || ^8.10.0 || >=9.10.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } } }, "node_modules/eslint-config-prettier": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-3.1.0.tgz", - "integrity": "sha512-QYGfmzuc4q4J6XIhlp8vRKdI/fI0tQfQPy1dME3UOLprE+v4ssH/3W9LM2Q7h5qBcy5m0ehCrBDU2YF8q6OY8w==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.0.1.tgz", + "integrity": "sha512-lZBts941cyJyeaooiKxAtzoPHTN+GbQTJFAIdQbRhA4/8whaAraEh47Whw/ZFfrjNSnlAxqfm9i0XVAEkULjCw==", "dev": true, - "dependencies": { - "get-stdin": "^6.0.0" - }, "bin": { - "eslint-config-prettier-check": "bin/cli.js" + "eslint-config-prettier": "build/bin/cli.js" }, "peerDependencies": { - "eslint": ">=3.14.1" + "eslint": ">=7.0.0" } }, "node_modules/eslint-plugin-prettier": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.0.0.tgz", - "integrity": "sha512-4g11opzhqq/8+AMmo5Vc2Gn7z9alZ4JqrbZ+D4i8KlSyxeQhZHlmIrY8U9Akf514MoEhogPa87Jgkq87aZ2Ohw==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.1.tgz", + "integrity": "sha512-gH3iR3g4JfF+yYPaJYkN7jEl9QbweL/YfkoRlNnuIEHEz1vHVlCmWOS+eGGiRuzHQXdJFCOTxRgvju9b8VUmrw==", "dev": true, "dependencies": { - "prettier-linter-helpers": "^1.0.0" + "prettier-linter-helpers": "^1.0.0", + "synckit": "^0.9.1" }, "engines": { - "node": ">=6.0.0" + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-plugin-prettier" }, "peerDependencies": { - "eslint": ">= 5.0.0", - "prettier": ">= 1.13.0" + "@types/eslint": ">=8.0.0", + "eslint": ">=8.0.0", + "eslint-config-prettier": "*", + "prettier": ">=3.0.0" + }, + "peerDependenciesMeta": { + "@types/eslint": { + "optional": true + }, + "eslint-config-prettier": { + "optional": true + } } }, "node_modules/eslint-scope": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz", + "integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/eslint/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/eslint/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/eslint/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/eslint/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/eslint/node_modules/escape-string-regexp": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.0.tgz", - "integrity": "sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA==", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "dependencies": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": ">=4.0.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint-utils": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", - "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", + "node_modules/eslint/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "dependencies": { - "eslint-visitor-keys": "^1.1.0" + "p-locate": "^5.0.0" }, "engines": { - "node": ">=6" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", - "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", + "node_modules/eslint/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/eslint/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint-visitor-keys": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", - "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", + "node_modules/eslint/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint/node_modules/debug": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.0.tgz", - "integrity": "sha512-heNPJUJIqC+xB6ayLAMHaIrmN9HKa7aQO8MGqKpvCA+uJYVcvR6l5kgdrhRuwPFHU7P5/A1w0BjByPHwpfTDKg==", - "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", + "node_modules/eslint/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "dependencies": { - "ms": "^2.1.1" + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/eslint/node_modules/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 - }, "node_modules/espree": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-4.1.0.tgz", - "integrity": "sha512-I5BycZW6FCVIub93TeVY1s7vjhP9CY6cXCznIRfiig7nRviKZYdRnj/sHEWC6A7WE9RDWOFq9+7OsWSYz8qv2w==", + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", + "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", "dev": true, "dependencies": { - "acorn": "^6.0.2", - "acorn-jsx": "^5.0.0", - "eslint-visitor-keys": "^1.0.0" + "acorn": "^8.14.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.0" }, "engines": { - "node": ">=6.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/esprima": { @@ -1314,42 +1638,42 @@ } }, "node_modules/esquery": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", - "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", "dev": true, "dependencies": { - "estraverse": "^4.0.0" + "estraverse": "^5.1.0" }, "engines": { - "node": ">=0.6" + "node": ">=0.10" } }, "node_modules/esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, "dependencies": { - "estraverse": "^4.1.0" + "estraverse": "^5.2.0" }, "engines": { "node": ">=4.0" } }, "node_modules/estraverse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=4.0" } }, "node_modules/esutils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, "engines": { "node": ">=0.10.0" @@ -1361,20 +1685,6 @@ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", "dev": true }, - "node_modules/external-editor": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.0.3.tgz", - "integrity": "sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA==", - "dev": true, - "dependencies": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", @@ -1384,6 +1694,12 @@ "node >=0.6.0" ] }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, "node_modules/fast-diff": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", @@ -1399,32 +1715,19 @@ "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, - "node_modules/figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", - "dev": true, - "dependencies": { - "escape-string-regexp": "^1.0.5" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/file-entry-cache": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", - "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", "dev": true, "dependencies": { - "flat-cache": "^1.2.1", - "object-assign": "^4.0.1" + "flat-cache": "^4.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=16.0.0" } }, "node_modules/finalhandler": { @@ -1476,20 +1779,24 @@ } }, "node_modules/flat-cache": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz", - "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", "dev": true, "dependencies": { - "circular-json": "^0.3.1", - "del": "^2.0.2", - "graceful-fs": "^4.1.2", - "write": "^0.2.1" + "flatted": "^3.2.9", + "keyv": "^4.5.4" }, "engines": { - "node": ">=0.10.0" + "node": ">=16" } }, + "node_modules/flatted": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.2.tgz", + "integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==", + "dev": true + }, "node_modules/for-each": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", @@ -1512,65 +1819,6 @@ "node": ">=8.0.0" } }, - "node_modules/foreground-child/node_modules/cross-spawn": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.1.tgz", - "integrity": "sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/foreground-child/node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/foreground-child/node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/foreground-child/node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/foreground-child/node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", @@ -1612,12 +1860,6 @@ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, "node_modules/gensync": { "version": "1.0.0-beta.1", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", @@ -1636,15 +1878,6 @@ "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/get-stdin": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", - "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", @@ -1671,30 +1904,28 @@ "node": "*" } }, - "node_modules/globals": { - "version": "11.8.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.8.0.tgz", - "integrity": "sha512-io6LkyPVuzCHBSQV9fmOwxZkUk6nIaGmxheLDgmuFv89j0fm2aqDbIXKAGfzCMHqz3HLF2Zf8WSG6VqMh2qFmA==", + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, "engines": { - "node": ">=4" + "node": ">=10.13.0" } }, - "node_modules/globby": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", - "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", + "node_modules/globals": { + "version": "15.14.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.14.0.tgz", + "integrity": "sha512-OkToC372DtlQeje9/zHIo5CT8lRP/FUgEOKBEhU4e0abL7J7CD24fD9ohiLN5hagG/kWCYj4K5oaxxtj2Z0Dig==", "dev": true, - "dependencies": { - "array-union": "^1.0.1", - "arrify": "^1.0.0", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, "engines": { - "node": ">=0.10.0" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/graceful-fs": { @@ -1826,25 +2057,29 @@ "npm": ">=1.3.7" } }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, "engines": { - "node": ">=0.10.0" + "node": ">= 4" } }, - "node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, "engines": { - "node": ">= 4" + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/imurmurhash": { @@ -1881,30 +2116,6 @@ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", "dev": true }, - "node_modules/inquirer": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.2.0.tgz", - "integrity": "sha512-QIEQG4YyQ2UYZGDC4srMZ7BjHOmNk1lR2JQj5UknBapklm6WHA+VVH7N+sUdX3A7NeCfGF8o4X1S3Ao7nAcIeg==", - "dev": true, - "dependencies": { - "ansi-escapes": "^3.0.0", - "chalk": "^2.0.0", - "cli-cursor": "^2.1.0", - "cli-width": "^2.0.0", - "external-editor": "^3.0.0", - "figures": "^2.0.0", - "lodash": "^4.17.10", - "mute-stream": "0.0.7", - "run-async": "^2.2.0", - "rxjs": "^6.1.0", - "string-width": "^2.1.0", - "strip-ansi": "^4.0.0", - "through": "^2.3.6" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/is-callable": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", @@ -1923,54 +2134,27 @@ "node": ">= 0.4" } }, - "node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/is-path-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", - "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-path-in-cwd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", - "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, - "dependencies": { - "is-path-inside": "^1.0.0" - }, "engines": { "node": ">=0.10.0" } }, - "node_modules/is-path-inside": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", - "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, "dependencies": { - "path-is-inside": "^1.0.1" + "is-extglob": "^2.1.1" }, "engines": { "node": ">=0.10.0" } }, - "node_modules/is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", - "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", - "dev": true - }, "node_modules/is-regex": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", @@ -1983,12 +2167,6 @@ "node": ">= 0.4" } }, - "node_modules/is-resolvable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", - "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", - "dev": true - }, "node_modules/is-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", @@ -2111,29 +2289,6 @@ "node": ">=8" } }, - "node_modules/istanbul-lib-processinfo/node_modules/cross-spawn": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.1.tgz", - "integrity": "sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/istanbul-lib-processinfo/node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/istanbul-lib-processinfo/node_modules/rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -2149,42 +2304,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/istanbul-lib-processinfo/node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-processinfo/node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-processinfo/node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/istanbul-lib-report": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", @@ -2351,21 +2470,9 @@ "dev": true, "bin": { "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jsdoc/node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + }, + "engines": { + "node": ">=10" } }, "node_modules/jsesc": { @@ -2380,6 +2487,12 @@ "node": ">=4" } }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, "node_modules/json-int64": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-int64/-/json-int64-1.0.2.tgz", @@ -2440,6 +2553,15 @@ "node": ">=0.6.0" } }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, "node_modules/klaw": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz", @@ -2450,13 +2572,13 @@ } }, "node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" }, "engines": { "node": ">= 0.8.0" @@ -2495,6 +2617,12 @@ "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", "dev": true }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, "node_modules/make-dir": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.0.2.tgz", @@ -2590,15 +2718,6 @@ "node": ">= 0.6" } }, - "node_modules/mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -2620,42 +2739,18 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, "node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true }, - "node_modules/mute-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", - "dev": true - }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, - "node_modules/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_modules/node-gyp-build": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-3.7.0.tgz", @@ -2779,15 +2874,6 @@ "node": "*" } }, - "node_modules/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, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/object-inspect": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz", @@ -2824,44 +2910,23 @@ "wrappy": "1" } }, - "node_modules/onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", - "dev": true, - "dependencies": { - "mimic-fn": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/optionator": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", - "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.4", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "wordwrap": "~1.0.0" + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" }, "engines": { "node": ">= 0.8.0" } }, - "node_modules/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=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/p-limit": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", @@ -2931,6 +2996,18 @@ "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", "dev": true }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/parseurl": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", @@ -2958,19 +3035,13 @@ "node": ">=0.10.0" } }, - "node_modules/path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, "node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/performance-now": { @@ -2979,36 +3050,6 @@ "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", "dev": true }, - "node_modules/pify": { - "version": "2.3.0", - "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/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, - "dependencies": { - "pinkie": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/pkg-dir": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", @@ -3021,34 +3062,28 @@ "node": ">=8" } }, - "node_modules/pluralize": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", - "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, "engines": { "node": ">= 0.8.0" } }, "node_modules/prettier": { - "version": "1.14.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.14.3.tgz", - "integrity": "sha512-qZDVnCrnpsRJJq5nSsiHCE3BYMED2OtsI+cmzIzF1QIfqm5ALf8tEJcO27zV1gKNKRPdhjO0dNWnrzssDQ1tFg==", + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.2.tgz", + "integrity": "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==", "dev": true, "bin": { - "prettier": "bin-prettier.js" + "prettier": "bin/prettier.cjs" }, "engines": { - "node": ">=4" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" } }, "node_modules/prettier-linter-helpers": { @@ -3075,15 +3110,6 @@ "node": ">=8" } }, - "node_modules/progress": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.1.tgz", - "integrity": "sha512-OE+a6vzqazc+K6LxJrX5UPyKFvGnL5CYmq2jFGNIBWHpc4QyE49/YOumcrpQFJpfejmvRtbJzgO1zPmMCqlbBg==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/psl": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", @@ -3117,15 +3143,6 @@ "node": ">=0.6" } }, - "node_modules/regexpp": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", - "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", - "dev": true, - "engines": { - "node": ">=6.5.0" - } - }, "node_modules/release-zalgo": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", @@ -3185,19 +3202,6 @@ "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true }, - "node_modules/require-uncached": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", - "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", - "dev": true, - "dependencies": { - "caller-path": "^0.1.0", - "resolve-from": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/requizzle": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.3.tgz", @@ -3208,23 +3212,10 @@ } }, "node_modules/resolve-from": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", - "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, - "dependencies": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" - }, "engines": { "node": ">=4" } @@ -3238,42 +3229,6 @@ "through": "~2.3.4" } }, - "node_modules/rimraf": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", - "dev": true, - "dependencies": { - "glob": "^7.0.5" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/run-async": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", - "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", - "dev": true, - "dependencies": { - "is-promise": "^2.1.0" - }, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/rxjs": { - "version": "6.3.3", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz", - "integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==", - "dev": true, - "dependencies": { - "tslib": "^1.9.0" - }, - "engines": { - "npm": ">=2.0.0" - } - }, "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -3302,24 +3257,24 @@ "dev": true }, "node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "dependencies": { - "shebang-regex": "^1.0.0" + "shebang-regex": "^3.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, "node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, "node_modules/signal-exit": { @@ -3328,18 +3283,6 @@ "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", "dev": true }, - "node_modules/slice-ansi": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", - "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", - "dev": true, - "dependencies": { - "is-fullwidth-code-point": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/spawn-wrap": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", @@ -3372,21 +3315,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/spawn-wrap/node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", @@ -3427,19 +3355,6 @@ "node": ">= 0.6" } }, - "node_modules/string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "dependencies": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/string.prototype.trim": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz", @@ -3454,18 +3369,6 @@ "node": ">= 0.4" } }, - "node_modules/strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "dependencies": { - "ansi-regex": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/strip-bom": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", @@ -3476,12 +3379,15 @@ } }, "node_modules/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=", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/supports-color": { @@ -3496,19 +3402,20 @@ "node": ">=4" } }, - "node_modules/table": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/table/-/table-5.1.0.tgz", - "integrity": "sha512-e542in22ZLhD/fOIuXs/8yDZ9W61ltF8daM88rkRNtgTIct+vI2fTnAyu/Db2TCfEcI8i7mjZz6meLq0nW7TYg==", + "node_modules/synckit": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.2.tgz", + "integrity": "sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==", "dev": true, "dependencies": { - "ajv": "^6.5.3", - "lodash": "^4.17.10", - "slice-ansi": "1.0.0", - "string-width": "^2.1.1" + "@pkgr/core": "^0.1.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=6.0.0" + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" } }, "node_modules/tape": { @@ -3584,30 +3491,12 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, "node_modules/through": { "version": "2.3.8", "resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", "dev": true }, - "node_modules/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "dependencies": { - "os-tmpdir": "~1.0.2" - }, - "engines": { - "node": ">=0.6.0" - } - }, "node_modules/to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -3631,9 +3520,9 @@ } }, "node_modules/tslib": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", - "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "dev": true }, "node_modules/tunnel-agent": { @@ -3655,12 +3544,12 @@ "dev": true }, "node_modules/type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, "dependencies": { - "prelude-ls": "~1.1.2" + "prelude-ls": "^1.2.1" }, "engines": { "node": ">= 0.8.0" @@ -3685,16 +3574,16 @@ } }, "node_modules/typescript": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.1.6.tgz", - "integrity": "sha512-tDMYfVtvpb96msS1lDX9MEdHrW4yOuZ4Kdc4Him9oU796XldPYF/t2+uKoX0BBa0hXXwDlqYQbXY5Rzjzc5hBA==", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", + "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { - "node": ">=4.2.0" + "node": ">=14.17" } }, "node_modules/uc.micro": { @@ -3709,6 +3598,12 @@ "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==", "dev": true }, + "node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "dev": true + }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -3777,15 +3672,18 @@ } }, "node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "dependencies": { "isexe": "^2.0.0" }, "bin": { - "which": "bin/which" + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" } }, "node_modules/which-module": { @@ -3794,11 +3692,14 @@ "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", "dev": true }, - "node_modules/wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, "node_modules/wrap-ansi": { "version": "6.2.0", @@ -3898,18 +3799,6 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, - "node_modules/write": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", - "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", - "dev": true, - "dependencies": { - "mkdirp": "^0.5.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/write-file-atomic": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.1.tgz", @@ -3923,9 +3812,9 @@ } }, "node_modules/ws": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.3.tgz", - "integrity": "sha512-jZArVERrMsKUatIdnLzqvcfydI85dvd/Fp1u/VOpfdDWQ4c9qWXe+VIeAbQ5FrDwciAkr+lzofXLz3Kuf26AOA==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.4.tgz", + "integrity": "sha512-fFCejsuC8f9kOSu9FYaOw8CdO68O3h5v0lg4p74o8JqWpwTf9tniOD+nOB78aWoVSS6WptVUmDrp/KPsMVBWFQ==", "dependencies": { "async-limiter": "~1.0.0" } @@ -4020,6 +3909,18 @@ "engines": { "node": ">=6" } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } } } diff --git a/package.json b/package.json index 47f9e874884..c86c155689e 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "type": "git", "url": "https://github.com/apache/thrift.git" }, - "version": "0.20.0", + "version": "0.22.0", "author": { "name": "Apache Thrift Developers", "email": "dev@thrift.apache.org", @@ -43,30 +43,32 @@ "ws": "^5.2.3" }, "devDependencies": { - "@types/node": "^10.12.6", + "@eslint/js": "^9.18.0", + "@types/node": "^22.10.5", "@types/node-int64": "^0.4.29", "@types/q": "^1.5.1", "buffer-equals": "^1.0.4", - "commander": "^2.14.1", + "commander": "^13.0.0", "connect": "^3.6.6", - "eslint": "^5.7.0", - "eslint-config-prettier": "^3.1.0", - "eslint-plugin-prettier": "^3.0.0", + "eslint": "^9.18.0", + "eslint-config-prettier": "^10.0.1", + "eslint-plugin-prettier": "^5.2.1", + "globals": "^15.14.0", "html-validator-cli": "^2.0.0", "jsdoc": "^4.0.2", "json-int64": "^1.0.2", "nyc": "^15.0.0", - "prettier": "^1.14.3", + "prettier": "^3.4.2", "tape": "^4.9.0", - "typescript": "^3.1.6", + "typescript": "^5.7.2", "utf-8-validate": "^5.0.0" }, "scripts": { "cover": "lib/nodejs/test/testAll.sh COVER", "test": "lib/nodejs/test/testAll.sh", "test-ts": "lib/nodets/test/testAll.sh", - "prettier": "prettier --write '**/*.js'", - "lint": "eslint lib/nodejs/. --ext .js", - "lint-tests": "eslint lib/nodejs/test/. --ext .js" + "prettier": "prettier --write '**/*.{js,mjs,ts}'", + "lint": "eslint lib/nodejs", + "lint-tests": "eslint lib/nodejs/test" } } diff --git a/rust-toolchain b/rust-toolchain index 902c74186fb..6b4de0a42b0 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1 +1 @@ -1.65.0 +1.83.0 diff --git a/sonar-project.properties b/sonar-project.properties index 258dfe913af..f88d43505cc 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -16,7 +16,7 @@ development, combines a software stack with a code generation engine to build services that work efficiently and seamlessly between all major languages. # Apache Thrift Version -sonar.projectVersion=0.20.0 +sonar.projectVersion=0.22.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 @@ -54,7 +54,7 @@ module1.sonar.projectName=Apache Thrift - Java Library module1.sonar.projectBaseDir=lib/java module1.sonar.sources=src module1.sonar.tests=test -module1.sonar.binaries=build/libs/libthrift-0.20.0.jar +module1.sonar.binaries=build/libs/libthrift-0.22.0.jar module1.sonar.libraries=build/deps/*.jar module1.sonar.language=java @@ -62,7 +62,7 @@ module2.sonar.projectName=Apache Thrift - Java Tutorial 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.20.0.jar +module2.sonar.libraries=lib/java/build/deps/*.jar,lib/java/build/libs/libthrift-0.22.0.jar module2.sonar.language=java module3.sonar.projectName=Apache Thrift - JavaScript Library diff --git a/test/DebugProtoTest.thrift b/test/DebugProtoTest.thrift index 3750d8d9360..22bf095f333 100644 --- a/test/DebugProtoTest.thrift +++ b/test/DebugProtoTest.thrift @@ -47,8 +47,9 @@ struct OneOfEach { 11: binary base64, 12: list byte_list = [1, 2, 3], 13: list i16_list = [1,2,3], - 14: list i64_list = [1,2,3] - 15: uuid rfc4122_uuid + 14: list i64_list = [1,2,3], + 15: uuid rfc4122_uuid, + 16: list rfc4122_uuid_list, } struct Bonk { diff --git a/test/ExceptionStruct.thrift b/test/ExceptionStruct.thrift new file mode 100644 index 00000000000..b962209b3d1 --- /dev/null +++ b/test/ExceptionStruct.thrift @@ -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. + */ + +namespace * test.ExceptionStruct + +enum ErrorCode { + GenericError, + ServerOverload, + InvalidData +} + +struct GetRequest { + 1: string id + 2: binary data // some arbitrary data +} + +struct GetResponse { + 1: i32 job_nr + 2: binary data // some arbitrary data +} + +struct BatchGetRequest { + 1: list requests +} + +struct BatchGetResponse { + 1: map responses, // key is id + 2: map errors, // key is id +} + +exception SomeException { + 2: ErrorCode error +} + +service Foo { + GetResponse get(1: GetRequest request) throws(1: SomeException error); + BatchGetResponse batchGet(1: BatchGetRequest request) throws(1: SomeException error); // may or may not be the same exception type, only throw exception when full request failed +} + +# eof diff --git a/test/Makefile.am b/test/Makefile.am index 696bd3be284..b82b89d431b 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -122,6 +122,9 @@ dist-hook: find $(distdir) -type d -name "__pycache__" | xargs rm -rf find $(distdir) -type f -name "*.pyc" | xargs rm -f +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ audit \ c_glib \ @@ -156,6 +159,7 @@ EXTRA_DIST = \ DoubleConstantsTest.thrift \ EnumContainersTest.thrift \ EnumTest.thrift \ + ExceptionStruct.thrift \ FullCamelTest.thrift \ Include.thrift \ Identifiers.thrift \ diff --git a/test/c_glib/Makefile.am b/test/c_glib/Makefile.am index f55a977d4ed..44714253ed9 100644 --- a/test/c_glib/Makefile.am +++ b/test/c_glib/Makefile.am @@ -78,5 +78,8 @@ dist-hook: $(RM) $(distdir)/libtestcglib.la find $(distdir) -type f -iname "*.o" | xargs rm -f +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ src diff --git a/test/cl/Makefile.am b/test/cl/Makefile.am index b5e72bcbbb9..c9705f15740 100755 --- a/test/cl/Makefile.am +++ b/test/cl/Makefile.am @@ -35,6 +35,9 @@ clean-local: $(RM) TestServer $(RM) TestClient +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ implementation.lisp \ make-test-client.lisp \ diff --git a/test/cpp/CMakeLists.txt b/test/cpp/CMakeLists.txt index f693a273daf..a6c1fd5cf4e 100644 --- a/test/cpp/CMakeLists.txt +++ b/test/cpp/CMakeLists.txt @@ -100,7 +100,7 @@ add_test(NAME SpecificNameTest COMMAND SpecificNameTest) # add_custom_command(OUTPUT gen-cpp/SecondService.cpp gen-cpp/SecondService.h gen-cpp/ThriftTest.cpp gen-cpp/ThriftTest.h gen-cpp/ThriftTest_types.cpp gen-cpp/ThriftTest_constants.cpp - COMMAND ${THRIFT_COMPILER} --gen cpp:templates,cob_style -r ${PROJECT_SOURCE_DIR}/test/v0.16/ThriftTest.thrift + COMMAND ${THRIFT_COMPILER} --gen cpp:templates,cob_style -r ${PROJECT_SOURCE_DIR}/test/ThriftTest.thrift ) add_custom_command(OUTPUT gen-cpp/Service.cpp diff --git a/test/cpp/Makefile.am b/test/cpp/Makefile.am index 9e8b6765b45..595f7a4fc73 100644 --- a/test/cpp/Makefile.am +++ b/test/cpp/Makefile.am @@ -116,6 +116,9 @@ clean-local: style-local: $(CPPSTYLE_CMD) +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ src/TestClient.cpp \ src/TestServer.cpp \ diff --git a/test/cpp/src/StressTest.cpp b/test/cpp/src/StressTest.cpp index 79a708e8f57..a42462059b8 100644 --- a/test/cpp/src/StressTest.cpp +++ b/test/cpp/src/StressTest.cpp @@ -155,7 +155,7 @@ class ClientThread : public Runnable { loopEchoString(); break; default: - cerr << "Unexpected loop type" << _loopType << endl; + cerr << "Unexpected loop type" << _loopType << '\n'; break; } @@ -280,23 +280,23 @@ int main(int argc, char** argv) { usage << argv[0] << " [--port=] [--server] [--server-type=] " "[--protocol-type=] [--workers=] " "[--clients=] [--loop=] " - "[--client-type=]" << endl + "[--client-type=]" << '\n' << "\tclients Number of client threads to create - 0 implies no clients, i.e. " - "server only. Default is " << clientCount << endl - << "\thelp Prints this help text." << endl - << "\tcall Service method to call. Default is " << callName << endl - << "\tloop The number of remote thrift calls each client makes. Default is " << loopCount << endl + "server only. Default is " << clientCount << '\n' + << "\thelp Prints this help text." << '\n' + << "\tcall Service method to call. Default is " << callName << '\n' + << "\tloop The number of remote thrift calls each client makes. Default is " << loopCount << '\n' << "\tport The port the server and clients should bind to " - "for thrift network connections. Default is " << port << endl - << "\tserver Run the Thrift server in this process. Default is " << runServer << endl - << "\tserver-type Type of server, \"simple\" or \"thread-pool\". Default is " << serverType << endl - << "\tprotocol-type Type of protocol, \"binary\", \"ascii\", or \"xml\". Default is " << protocolType << endl - << "\tlog-request Log all request to ./requestlog.tlog. Default is " << logRequests << endl - << "\treplay-request Replay requests from log file (./requestlog.tlog) Default is " << replayRequests << endl + "for thrift network connections. Default is " << port << '\n' + << "\tserver Run the Thrift server in this process. Default is " << runServer << '\n' + << "\tserver-type Type of server, \"simple\" or \"thread-pool\". Default is " << serverType << '\n' + << "\tprotocol-type Type of protocol, \"binary\", \"ascii\", or \"xml\". Default is " << protocolType << '\n' + << "\tlog-request Log all request to ./requestlog.tlog. Default is " << logRequests << '\n' + << "\treplay-request Replay requests from log file (./requestlog.tlog) Default is " << replayRequests << '\n' << "\tworkers Number of thread pools workers. Only valid " - "for thread-pool server type. Default is " << workerCount << endl - << "\tclient-type Type of client, \"regular\" or \"concurrent\". Default is " << clientType << endl - << endl; + "for thread-pool server type. Default is " << workerCount << '\n' + << "\tclient-type Type of client, \"regular\" or \"concurrent\". Default is " << clientType << '\n' + << '\n'; map args; @@ -386,7 +386,7 @@ int main(int argc, char** argv) { } } catch (std::exception& e) { - cerr << e.what() << endl; + cerr << e.what() << '\n'; cerr << usage.str(); } @@ -468,7 +468,7 @@ int main(int argc, char** argv) { server->setServerEventHandler(observer); std::shared_ptr serverThread = threadFactory->newThread(server); - cerr << "Starting the server on port " << port << endl; + cerr << "Starting the server on port " << port << '\n'; serverThread->start(); observer->waitForService(); @@ -538,7 +538,7 @@ int main(int argc, char** argv) { Synchronized s(monitor); threadCount = clientCount; - cerr << "Launch " << clientCount << " " << clientType << " client threads" << endl; + cerr << "Launch " << clientCount << " " << clientType << " client threads" << '\n'; time00 = std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count(); @@ -591,14 +591,14 @@ int main(int argc, char** argv) { averageTime /= clientCount; cout << "workers :" << workerCount << ", client : " << clientCount << ", loops : " << loopCount - << ", rate : " << (clientCount * loopCount * 1000) / ((double)(time01 - time00)) << endl; + << ", rate : " << (clientCount * loopCount * 1000) / ((double)(time01 - time00)) << '\n'; count_map count = serviceHandler->getCount(); count_map::iterator iter; for (iter = count.begin(); iter != count.end(); ++iter) { printf("%s => %d\n", iter->first, iter->second); } - cerr << "done." << endl; + cerr << "done." << '\n'; } return 0; diff --git a/test/cpp/src/StressTestNonBlocking.cpp b/test/cpp/src/StressTestNonBlocking.cpp index e94ecb2db11..d9d9ae606b5 100644 --- a/test/cpp/src/StressTestNonBlocking.cpp +++ b/test/cpp/src/StressTestNonBlocking.cpp @@ -152,7 +152,7 @@ class ClientThread : public Runnable { loopEchoString(); break; default: - cerr << "Unexpected loop type" << _loopType << endl; + cerr << "Unexpected loop type" << _loopType << '\n'; break; } @@ -253,24 +253,20 @@ int main(int argc, char** argv) { usage << argv[0] << " [--port=] [--server] [--server-type=] " "[--protocol-type=] [--workers=] " - "[--clients=] [--loop=]" << endl + "[--clients=] [--loop=]" << '\n' << "\tclients Number of client threads to create - 0 implies no clients, i.e. " - "server only. Default is " << clientCount << endl - << "\thelp Prints this help text." << endl - << "\tcall Service method to call. Default is " << callName << endl - << "\tloop The number of remote thrift calls each client makes. Default is " - << loopCount << endl << "\tport The port the server and clients should bind to " - "for thrift network connections. Default is " << port << endl - << "\tserver Run the Thrift server in this process. Default is " << runServer - << endl << "\tserver-type Type of server, \"simple\" or \"thread-pool\". Default is " - << serverType << endl - << "\tprotocol-type Type of protocol, \"binary\", \"ascii\", or \"xml\". Default is " - << protocolType << endl - << "\tlog-request Log all request to ./requestlog.tlog. Default is " << logRequests - << endl << "\treplay-request Replay requests from log file (./requestlog.tlog) Default is " - << replayRequests << endl << "\tworkers Number of thread pools workers. Only valid " - "for thread-pool server type. Default is " << workerCount - << endl; + "server only. Default is " << clientCount << '\n' + << "\thelp Prints this help text." << '\n' + << "\tcall Service method to call. Default is " << callName << '\n' + << "\tloop The number of remote thrift calls each client makes. Default is " << loopCount << '\n' + << "\tport The port the server and clients should bind to for thrift network " + "connections. Default is " << port << '\n' + << "\tserver Run the Thrift server in this process. Default is " << runServer << '\n' + << "\tserver-type Type of server, \"simple\" or \"thread-pool\". Default is " << serverType << '\n' + << "\tprotocol-type Type of protocol, \"binary\", \"ascii\", or \"xml\". Default is " << protocolType << '\n' + << "\tlog-request Log all request to ./requestlog.tlog. Default is " << logRequests << '\n' + << "\treplay-request Replay requests from log file (./requestlog.tlog) Default is " << replayRequests << '\n' + << "\tworkers Number of thread pools workers. Only valid for thread-pool server type. Default is " << workerCount << '\n'; map args; @@ -338,7 +334,7 @@ int main(int argc, char** argv) { } } catch (std::exception& e) { - cerr << e.what() << endl; + cerr << e.what() << '\n'; cerr << usage.str(); } @@ -416,7 +412,7 @@ int main(int argc, char** argv) { new TNonblockingServer(serviceProcessor, protocolFactory, nbSocket2, threadManager))); } - cerr << "Starting the server on port " << port << " and " << (port + 1) << endl; + cerr << "Starting the server on port " << port << " and " << (port + 1) << '\n'; serverThread->start(); serverThread2->start(); @@ -475,7 +471,7 @@ int main(int argc, char** argv) { Synchronized s(monitor); threadCount = clientCount; - cerr << "Launch " << clientCount << " client threads" << endl; + cerr << "Launch " << clientCount << " client threads" << '\n'; time00 = std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count(); @@ -528,14 +524,14 @@ int main(int argc, char** argv) { averageTime /= clientCount; cout << "workers :" << workerCount << ", client : " << clientCount << ", loops : " << loopCount - << ", rate : " << (clientCount * loopCount * 1000) / ((double)(time01 - time00)) << endl; + << ", rate : " << (clientCount * loopCount * 1000) / ((double)(time01 - time00)) << '\n'; count_map count = serviceHandler->getCount(); count_map::iterator iter; for (iter = count.begin(); iter != count.end(); ++iter) { printf("%s => %d\n", iter->first, iter->second); } - cerr << "done." << endl; + cerr << "done." << '\n'; } return 0; diff --git a/test/cpp/src/TestClient.cpp b/test/cpp/src/TestClient.cpp index c4146cc5cf5..64193c657c6 100644 --- a/test/cpp/src/TestClient.cpp +++ b/test/cpp/src/TestClient.cpp @@ -70,7 +70,7 @@ using namespace thrift::test; // template -class TPedanticProtocol : public Proto +class TPedanticProtocol : public Proto { public: TPedanticProtocol(std::shared_ptr& transport) @@ -98,7 +98,7 @@ class TPedanticProtocol : public Proto 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; + std::cout << "verified seqid " << m_last_seqid << " round trip OK" << '\n'; } */ return result; } @@ -127,9 +127,9 @@ static void testString_clientReturn(event_base* base, std::ostringstream os; os << "test" << testNr; const bool ok = (s == os.str()); - cout << "testString: " << s << " " << ((ok) ? "ok" : "failed") << endl; + cout << "testString: " << s << " " << ((ok) ? "ok" : "failed") << '\n'; } catch (TException& exn) { - cout << "Error: " << exn.what() << endl; + cout << "Error: " << exn.what() << '\n'; } if (testNr == 9) @@ -139,7 +139,7 @@ static void testString_clientReturn(event_base* base, static void testVoid_clientReturn(event_base* base, ThriftTestCobClient* client) { try { client->recv_testVoid(); - cout << "testVoid" << endl; + cout << "testVoid" << '\n'; for (int testNr = 0; testNr < 10; ++testNr) { std::ostringstream os; @@ -151,16 +151,16 @@ static void testVoid_clientReturn(event_base* base, ThriftTestCobClient* client) os.str()); } } catch (TException& exn) { - cout << "Error: " << exn.what() << endl; + cout << "Error: " << exn.what() << '\n'; } } // Workaround for absense of C++11 "auto" keyword. template bool print_eq(T expected, T actual) { - cout << "(" << actual << ")" << endl; + cout << "(" << actual << ")" << '\n'; if (expected != actual) { - cout << "*** FAILED ***" << endl << "Expected: " << expected << " but got: " << actual << endl; + cout << "*** FAILED ***" << '\n' << "Expected: " << expected << " but got: " << actual << '\n'; return false; } return true; @@ -174,7 +174,21 @@ bool print_eq(T expected, T actual) { } catch (TTransportException&) { \ throw; \ } catch (exception & ex) { \ - cout << "*** FAILED ***" << endl << ex.what() << endl; \ + cout << "*** FAILED ***" << '\n' << ex.what() << '\n'; \ + return_code |= ERR_BASETYPES; \ + } + +#define UUID_TEST(func, value, expected) \ + cout << #func "(" << value << ") = "; \ + try { \ + TUuid ret; \ + testClient.func(ret, value); \ + if (!print_eq(expected, ret)) \ + return_code |= ERR_BASETYPES; \ + } catch (TTransportException&) { \ + throw; \ + } catch (exception & ex) { \ + cout << "*** FAILED ***" << '\n' << ex.what() << '\n'; \ return_code |= ERR_BASETYPES; \ } @@ -246,7 +260,7 @@ int main(int argc, char** argv) { boost::program_options::notify(vm); if (vm.count("help")) { - cout << desc << endl; + cout << desc << '\n'; return ERR_UNKNOWN; } @@ -278,8 +292,8 @@ int main(int argc, char** argv) { } } catch (exception& e) { - cerr << e.what() << endl; - cout << desc << endl; + cerr << e.what() << '\n'; + cout << desc << '\n'; return ERR_UNKNOWN; } @@ -307,9 +321,9 @@ int main(int argc, char** argv) { std::shared_ptr protocol2; // SecondService for multiplexed if (ssl) { - cout << "Client Certificate File: " << certPath << endl; - cout << "Client Key File: " << keyPath << endl; - cout << "CA File: " << caPath << endl; + cout << "Client Certificate File: " << certPath << '\n'; + cout << "Client Key File: " << keyPath << '\n'; + cout << "CA File: " << caPath << '\n'; factory = std::shared_ptr(new TSSLSocketFactory()); factory->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"); @@ -374,14 +388,14 @@ int main(int argc, char** argv) { if (port != 0) { cout << host << ":" << port; } - cout << endl; + cout << '\n'; if (transport_type.compare("evhttp") == 0) { event_base* base = event_base_new(); - cout << "Libevent Version: " << event_get_version() << endl; - cout << "Libevent Method: " << event_base_get_method(base) << endl; + cout << "Libevent Version: " << event_get_version() << '\n'; + cout << "Libevent Method: " << event_base_get_method(base) << '\n'; #if LIBEVENT_VERSION_NUMBER >= 0x02000000 - cout << "Libevent Features: 0x" << hex << event_base_get_features(base) << endl; + cout << "Libevent Features: 0x" << hex << event_base_get_features(base) << '\n'; #endif std::shared_ptr protocolFactory(new TBinaryProtocolFactory()); @@ -409,7 +423,7 @@ int main(int argc, char** argv) { try { transport->open(); } catch (TTransportException& ex) { - cout << "Connect failed: " << ex.what() << endl; + cout << "Connect failed: " << ex.what() << '\n'; return ERR_UNKNOWN; } @@ -426,12 +440,12 @@ int main(int argc, char** argv) { try { cout << "testVoid()" << flush; testClient.testVoid(); - cout << " = void" << endl; + cout << " = void" << '\n'; } catch (TTransportException&) { // Stop here if transport got broken throw; } catch (exception& ex) { - cout << "*** FAILED ***" << endl << ex.what() << endl; + cout << "*** FAILED ***" << '\n' << ex.what() << '\n'; return_code |= ERR_BASETYPES; } @@ -441,9 +455,9 @@ int main(int argc, char** argv) { cout << "testString(\"Test\")" << flush; string s; testClient.testString(s, "Test"); - cout << " = " << s << endl; + cout << " = " << s << '\n'; if (s != "Test") { - cout << "*** FAILED ***" << endl; + cout << "*** FAILED ***" << '\n'; return_code |= ERR_BASETYPES; } @@ -459,9 +473,9 @@ int main(int argc, char** argv) { cout << "secondService.secondTestString(\"foo\") => " << flush; std::string result; ssc.secondtestString(result, "foo"); - cout << "{" << result << "}" << endl; + cout << "{" << result << "}" << '\n'; } catch (std::exception& e) { - cout << " *** FAILED *** " << e.what() << endl; + cout << " *** FAILED *** " << e.what() << '\n'; return_code |= ERR_EXCEPTIONS; } } @@ -502,16 +516,16 @@ int main(int argc, char** argv) { #endif cout << "testString(" << str << ") = " << flush; testClient.testString(s, str); - cout << s << endl; + cout << s << '\n'; if (s != str) { cout.imbue(locale("en_US.UTF8")); - cout << "*** FAILED ***" << endl << "Expected string: " << str << " but got: " << s << endl << "CLEAR"; + cout << "*** FAILED ***" << '\n' << "Expected string: " << str << " but got: " << s << '\n' << "CLEAR"; return_code |= ERR_BASETYPES; } } catch (TTransportException&) { throw; } catch (exception& ex) { - cout << "*** FAILED ***" << endl << ex.what() << endl; + cout << "*** FAILED ***" << '\n' << ex.what() << '\n'; return_code |= ERR_BASETYPES; return return_code; } @@ -525,11 +539,11 @@ int main(int argc, char** argv) { " char-to-test-json-parsing: ]] \"]] \\\" }}}{ [[[ "); cout << "testString(" << str << ") = " << flush; testClient.testString(s, str); - cout << s << endl; + cout << s << '\n'; if (s != str) { cout.imbue(locale("en_US.UTF8")); - cout << "*** FAILED ***" << endl - << "Expected string: " << str << " but got: " << s << endl + cout << "*** FAILED ***" << '\n' + << "Expected string: " << str << " but got: " << s << '\n' << "CLEAR"; ; return_code |= ERR_BASETYPES; @@ -537,7 +551,7 @@ int main(int argc, char** argv) { } catch (TTransportException&) { throw; } catch (exception& ex) { - cout << "*** FAILED ***" << endl << ex.what() << endl; + cout << "*** FAILED ***" << '\n' << ex.what() << '\n'; return_code |= ERR_BASETYPES; return return_code; } @@ -602,15 +616,15 @@ int main(int argc, char** argv) { double expected = pow(static_cast(10), 307); cout << "testDouble(" << expected << ") = " << flush; double actual = testClient.testDouble(expected); - cout << "(" << actual << ")" << endl; + cout << "(" << actual << ")" << '\n'; if (expected - actual > pow(static_cast(10), 292)) { - cout << "*** FAILED ***" << endl - << "Expected: " << expected << " but got: " << actual << endl; + cout << "*** FAILED ***" << '\n' + << "Expected: " << expected << " but got: " << actual << '\n'; } } catch (TTransportException&) { throw; } catch (exception& ex) { - cout << "*** FAILED ***" << endl << ex.what() << endl; + cout << "*** FAILED ***" << '\n' << ex.what() << '\n'; return_code |= ERR_BASETYPES; } @@ -618,15 +632,15 @@ int main(int argc, char** argv) { double expected = pow(static_cast(10), -292); cout << "testDouble(" << expected << ") = " << flush; double actual = testClient.testDouble(expected); - cout << "(" << actual << ")" << endl; + cout << "(" << actual << ")" << '\n'; if (expected - actual > pow(static_cast(10), -307)) { - cout << "*** FAILED ***" << endl - << "Expected: " << expected << " but got: " << actual << endl; + cout << "*** FAILED ***" << '\n' + << "Expected: " << expected << " but got: " << actual << '\n'; } } catch (TTransportException&) { throw; } catch (exception& ex) { - cout << "*** FAILED ***" << endl << ex.what() << endl; + cout << "*** FAILED ***" << '\n' << ex.what() << '\n'; return_code |= ERR_BASETYPES; } @@ -638,6 +652,15 @@ int main(int argc, char** argv) { if (i > 0) { i *= 2; } else { ++i; } } + /** + * UUID TEST + */ + const TUuid expected_uuid{"5e2ab188-1726-4e75-a04f-1ed9a6a89c4c"}; + UUID_TEST(testUuid, TUuid{"{5e2ab188-1726-4e75-a04f-1ed9a6a89c4c}"}, expected_uuid); + UUID_TEST(testUuid, TUuid{"5e2ab188-1726-4e75-a04f-1ed9a6a89c4c"}, expected_uuid); + UUID_TEST(testUuid, TUuid{"5e2ab18817264e75a04f1ed9a6a89c4c"}, expected_uuid); + UUID_TEST(testUuid, TUuid{"{5e2ab18817264e75a04f1ed9a6a89c4c}"}, expected_uuid); + UUID_TEST(testUuid, TUuid{}, TUuid{"00000000-0000-0000-0000-000000000000"}); /** * STRUCT TEST @@ -656,7 +679,7 @@ int main(int argc, char** argv) { in.i32_thing, in.i64_thing); if (in != out) { - cout << "*** FAILED ***" << endl; + cout << "*** FAILED ***" << '\n'; return_code |= ERR_STRUCTS; } @@ -679,7 +702,7 @@ int main(int argc, char** argv) { in.i64_thing, in2.i32_thing); if (in2 != out2) { - cout << "*** FAILED ***" << endl; + cout << "*** FAILED ***" << '\n'; return_code |= ERR_STRUCTS; } @@ -714,9 +737,9 @@ int main(int argc, char** argv) { } cout << m_iter->first << " => " << m_iter->second; } - cout << "}" << endl; + cout << "}" << '\n'; if (mapin != mapout) { - cout << "*** FAILED ***" << endl; + cout << "*** FAILED ***" << '\n'; return_code |= ERR_CONTAINERS; } @@ -739,15 +762,15 @@ int main(int argc, char** argv) { first = false; cout << it->first << " => " << it->second; } - cout << "}" << endl; + cout << "}" << '\n'; if (smapin != smapout) { - cout << "*** FAILED ***" << endl; + cout << "*** FAILED ***" << '\n'; return_code |= ERR_CONTAINERS; } } catch (TTransportException&) { throw; } catch (exception& ex) { - cout << "*** FAILED ***" << endl << ex.what() << endl; + cout << "*** FAILED ***" << '\n' << ex.what() << '\n'; return_code |= ERR_CONTAINERS; } @@ -782,9 +805,9 @@ int main(int argc, char** argv) { } cout << *s_iter; } - cout << "}" << endl; + cout << "}" << '\n'; if (setin != setout) { - cout << "*** FAILED ***" << endl; + cout << "*** FAILED ***" << '\n'; return_code |= ERR_CONTAINERS; } @@ -796,14 +819,14 @@ int main(int argc, char** argv) { vector listout; testClient.testList(listout, vector()); if (!listout.empty()) { - cout << "*** FAILED ***" << endl; - cout << "invalid length: " << listout.size() << endl; + cout << "*** FAILED ***" << '\n'; + cout << "invalid length: " << listout.size() << '\n'; return_code |= ERR_CONTAINERS; } } catch (TTransportException&) { throw; } catch (exception& ex) { - cout << "*** FAILED ***" << endl << ex.what() << endl; + cout << "*** FAILED ***" << '\n' << ex.what() << '\n'; return_code |= ERR_CONTAINERS; } try { @@ -835,15 +858,15 @@ int main(int argc, char** argv) { } cout << *l_iter; } - cout << "}" << endl; + cout << "}" << '\n'; if (listin != listout) { - cout << "*** FAILED ***" << endl; + cout << "*** FAILED ***" << '\n'; return_code |= ERR_CONTAINERS; } } catch (TTransportException&) { throw; } catch (exception& ex) { - cout << "*** FAILED ***" << endl << ex.what() << endl; + cout << "*** FAILED ***" << '\n' << ex.what() << '\n'; return_code |= ERR_CONTAINERS; } @@ -852,41 +875,41 @@ int main(int argc, char** argv) { */ cout << "testEnum(ONE)" << flush; Numberz::type ret = testClient.testEnum(Numberz::ONE); - cout << " = " << ret << endl; + cout << " = " << ret << '\n'; if (ret != Numberz::ONE) { - cout << "*** FAILED ***" << endl; + cout << "*** FAILED ***" << '\n'; return_code |= ERR_STRUCTS; } cout << "testEnum(TWO)" << flush; ret = testClient.testEnum(Numberz::TWO); - cout << " = " << ret << endl; + cout << " = " << ret << '\n'; if (ret != Numberz::TWO) { - cout << "*** FAILED ***" << endl; + cout << "*** FAILED ***" << '\n'; return_code |= ERR_STRUCTS; } cout << "testEnum(THREE)" << flush; ret = testClient.testEnum(Numberz::THREE); - cout << " = " << ret << endl; + cout << " = " << ret << '\n'; if (ret != Numberz::THREE) { - cout << "*** FAILED ***" << endl; + cout << "*** FAILED ***" << '\n'; return_code |= ERR_STRUCTS; } cout << "testEnum(FIVE)" << flush; ret = testClient.testEnum(Numberz::FIVE); - cout << " = " << ret << endl; + cout << " = " << ret << '\n'; if (ret != Numberz::FIVE) { - cout << "*** FAILED ***" << endl; + cout << "*** FAILED ***" << '\n'; return_code |= ERR_STRUCTS; } cout << "testEnum(EIGHT)" << flush; ret = testClient.testEnum(Numberz::EIGHT); - cout << " = " << ret << endl; + cout << " = " << ret << '\n'; if (ret != Numberz::EIGHT) { - cout << "*** FAILED ***" << endl; + cout << "*** FAILED ***" << '\n'; return_code |= ERR_STRUCTS; } @@ -895,9 +918,9 @@ int main(int argc, char** argv) { */ cout << "testTypedef(309858235082523)" << flush; UserId uid = testClient.testTypedef(309858235082523LL); - cout << " = " << uid << endl; + cout << " = " << uid << '\n'; if (uid != 309858235082523LL) { - cout << "*** FAILED ***" << endl; + cout << "*** FAILED ***" << '\n'; return_code |= ERR_STRUCTS; } @@ -917,7 +940,7 @@ int main(int argc, char** argv) { } cout << "}, "; } - cout << "}" << endl; + cout << "}" << '\n'; if (mm.size() != 2 || mm[-4][-4] != -4 || mm[-4][-3] != -3 || @@ -927,7 +950,7 @@ int main(int argc, char** argv) { mm[4][3] != 3 || mm[4][2] != 2 || mm[4][1] != 1) { - cout << "*** FAILED ***" << endl; + cout << "*** FAILED ***" << '\n'; return_code |= ERR_CONTAINERS; } @@ -984,7 +1007,7 @@ int main(int argc, char** argv) { } cout << "}, "; } - cout << "}" << endl; + cout << "}" << '\n'; bool failed = false; map >::const_iterator it1 = whoa.find(UserId(1)); if (whoa.size() != 2) { @@ -1012,7 +1035,7 @@ int main(int argc, char** argv) { } } if (failed) { - cout << "*** FAILED ***" << endl; + cout << "*** FAILED ***" << '\n'; return_code |= ERR_STRUCTS; } } @@ -1020,7 +1043,7 @@ int main(int argc, char** argv) { /** * MULTI TEST */ - cout << "testMulti()" << endl; + cout << "testMulti()" << '\n'; try { map mul_map; Xtruct mul_result; @@ -1033,13 +1056,13 @@ int main(int argc, char** argv) { xxs.i32_thing = 4242; xxs.i64_thing = 424242; if (mul_result != xxs) { - cout << "*** FAILED ***" << endl; + cout << "*** FAILED ***" << '\n'; return_code |= ERR_STRUCTS; } } catch (TTransportException&) { throw; } catch (exception& ex) { - cout << "*** FAILED ***" << endl << ex.what() << endl; + cout << "*** FAILED ***" << '\n' << ex.what() << '\n'; return_code |= ERR_STRUCTS; } @@ -1048,7 +1071,7 @@ int main(int argc, char** argv) { try { cout << "testClient.testException(\"Xception\") =>" << flush; testClient.testException("Xception"); - cout << " void\n*** FAILED ***" << endl; + cout << " void\n*** FAILED ***" << '\n'; return_code |= ERR_EXCEPTIONS; } catch (Xception& e) { @@ -1058,19 +1081,19 @@ int main(int argc, char** argv) { try { cout << "testClient.testException(\"TException\") =>" << flush; testClient.testException("TException"); - cout << " void\n*** FAILED ***" << endl; + cout << " void\n*** FAILED ***" << '\n'; return_code |= ERR_EXCEPTIONS; } catch (const TException&) { - cout << " Caught TException" << endl; + cout << " Caught TException" << '\n'; } try { cout << "testClient.testException(\"success\") =>" << flush; testClient.testException("success"); - cout << " void" << endl; + cout << " void" << '\n'; } catch (exception & ex) { \ - cout << "*** FAILED ***" << endl << ex.what() << endl; + cout << "*** FAILED ***" << '\n' << ex.what() << '\n'; return_code |= ERR_EXCEPTIONS; } @@ -1080,7 +1103,7 @@ int main(int argc, char** argv) { cout << "testClient.testMultiException(\"Xception\", \"test 1\") =>" << flush; Xtruct result; testClient.testMultiException(result, "Xception", "test 1"); - cout << " result\n*** FAILED ***" << endl; + cout << " result\n*** FAILED ***" << '\n'; return_code |= ERR_EXCEPTIONS; } catch (Xception& e) { printf(" {%u, \"%s\"}\n", e.errorCode, e.message.c_str()); @@ -1090,7 +1113,7 @@ int main(int argc, char** argv) { cout << "testClient.testMultiException(\"Xception2\", \"test 2\") =>" << flush; Xtruct result; testClient.testMultiException(result, "Xception2", "test 2"); - cout << " result\n*** FAILED ***" << endl; + cout << " result\n*** FAILED ***" << '\n'; return_code |= ERR_EXCEPTIONS; } catch (Xception2& e) { @@ -1103,7 +1126,7 @@ int main(int argc, char** argv) { testClient.testMultiException(result, "success", "test 3"); printf(" {{\"%s\"}}\n", result.string_thing.c_str()); } catch (exception & ex) { \ - cout << "*** FAILED ***" << endl << ex.what() << endl; + cout << "*** FAILED ***" << '\n' << ex.what() << '\n'; return_code |= ERR_EXCEPTIONS; } @@ -1134,16 +1157,16 @@ int main(int argc, char** argv) { */ cout << "re-test testI32(-1)" << flush; int i32 = testClient.testI32(-1); - cout << " = " << i32 << endl; + cout << " = " << i32 << '\n'; if (i32 != -1) return_code |= ERR_BASETYPES; - cout << endl << "All tests done." << endl << flush; + cout << '\n' << "All tests done." << '\n' << flush; uint64_t stop = now(); uint64_t tot = stop - start; - cout << "Total time: " << stop - start << " us" << endl; + cout << "Total time: " << stop - start << " us" << '\n'; time_tot += tot; if (time_min == 0 || tot < time_min) { @@ -1160,9 +1183,9 @@ int main(int argc, char** argv) { uint64_t time_avg = time_tot / numTests; - cout << "Min time: " << time_min << " us" << endl; - cout << "Max time: " << time_max << " us" << endl; - cout << "Avg time: " << time_avg << " us" << endl; + cout << "Min time: " << time_min << " us" << '\n'; + cout << "Max time: " << time_max << " us" << '\n'; + cout << "Avg time: " << time_avg << " us" << '\n'; return return_code; } @@ -1204,26 +1227,26 @@ int binary_test(ThriftTestClient& testClient, string::size_type siz) string bin_request; string bin_result; - cout << "testBinary(siz = " << siz << ")" << endl; + cout << "testBinary(siz = " << siz << ")" << '\n'; binary_fill(bin_request, siz); try { testClient.testBinary(bin_result, bin_request); if (bin_request.size() != bin_result.size()) { - cout << "*** FAILED: request size " << bin_request.size() << "; result size " << bin_result.size() << endl; + cout << "*** FAILED: request size " << bin_request.size() << "; result size " << bin_result.size() << '\n'; return ERR_BASETYPES; } for (string::size_type i = 0; i < siz; ++i) { if (bin_request.at(i) != bin_result.at(i)) { - cout << "*** FAILED: at position " << i << " request[i] is h" << hex << bin_request.at(i) << " result[i] is h" << hex << bin_result.at(i) << endl; + cout << "*** FAILED: at position " << i << " request[i] is h" << hex << bin_request.at(i) << " result[i] is h" << hex << bin_result.at(i) << '\n'; return ERR_BASETYPES; } } } catch (TTransportException&) { throw; } catch (exception& ex) { - cout << "*** FAILED ***" << endl << ex.what() << endl; + cout << "*** FAILED ***" << '\n' << ex.what() << '\n'; return ERR_BASETYPES; } diff --git a/test/cpp/src/TestServer.cpp b/test/cpp/src/TestServer.cpp index 65317f89c13..858fffa3852 100644 --- a/test/cpp/src/TestServer.cpp +++ b/test/cpp/src/TestServer.cpp @@ -132,6 +132,11 @@ class TestHandler : public ThriftTestIf { _return = thing; } + void testUuid(apache::thrift::TUuid& _return, const apache::thrift::TUuid& thing) override { + printf("testUuid(\"{%s}\")\n", to_string(thing).c_str()); + _return = thing; + } + void testStruct(Xtruct& out, const Xtruct& thing) override { printf("testStruct({\"%s\", %d, %d, %" PRId64 "})\n", thing.string_thing.c_str(), @@ -389,7 +394,7 @@ class TestProcessorEventHandler : public TProcessorEventHandler { } void communicate(const char* event, void* ctx, const char* fn_name) { - std::cout << event << ": " << *static_cast(ctx) << " = " << fn_name << std::endl; + std::cout << event << ": " << *static_cast(ctx) << " = " << fn_name << '\n'; } }; @@ -442,6 +447,12 @@ class TestHandlerAsync : public ThriftTestCobSvIf { cob(res); } + void testUuid(::std::function cob, const apache::thrift::TUuid& thing) override { + TUuid res; + _delegate->testUuid(res, thing); + cob(res); + } + void testStruct(std::function cob, const Xtruct& thing) override { Xtruct res; _delegate->testStruct(res, thing); @@ -645,7 +656,7 @@ int main(int argc, char** argv) { } } catch (std::exception& e) { - cerr << e.what() << endl; + cerr << e.what() << '\n'; cout << desc << "\n"; return 1; } @@ -757,7 +768,7 @@ int main(int argc, char** argv) { if (port != 0) { cout << port; } - cout << endl; + cout << '\n'; // Multiplexed Processor if needed if (boost::starts_with(protocol_type, "multi")) { @@ -813,7 +824,7 @@ int main(int argc, char** argv) { : new transport::TNonblockingServerSocket(port)); server.reset(new TNonblockingServer(testProcessor, protocolFactory, nbSocket)); } else { - cerr << "server-type nonblocking requires transport of http or framed" << endl; + cerr << "server-type nonblocking requires transport of http or framed" << '\n'; exit(1); } } @@ -847,6 +858,6 @@ int main(int argc, char** argv) { server.reset(); } - cout << "done." << endl; + cout << "done." << '\n'; return 0; } diff --git a/test/crossrunner/compat.py b/test/crossrunner/compat.py deleted file mode 100644 index 932a48cd6ad..00000000000 --- a/test/crossrunner/compat.py +++ /dev/null @@ -1,24 +0,0 @@ -import os -import sys - -if sys.version_info[0] == 2: - _ENCODE = sys.getfilesystemencoding() - - def path_join(*args): - bin_args = map(lambda a: a.decode(_ENCODE), args) - return os.path.join(*bin_args).encode(_ENCODE) - - def str_join(left, right): - bin_args = map(lambda a: a.decode(_ENCODE), right) - b = left.decode(_ENCODE) - return b.join(bin_args).encode(_ENCODE) - - logfile_open = open - -else: - - path_join = os.path.join - str_join = str.join - - def logfile_open(*args): - return open(*args, errors='replace') diff --git a/test/crossrunner/report.py b/test/crossrunner/report.py index 5baf1619524..9231a8b1ace 100644 --- a/test/crossrunner/report.py +++ b/test/crossrunner/report.py @@ -17,7 +17,6 @@ # under the License. # -from __future__ import print_function import datetime import json import multiprocessing @@ -29,7 +28,6 @@ import time import traceback -from .compat import logfile_open, path_join, str_join from .test import TestEntry LOG_DIR = 'log' @@ -38,6 +36,10 @@ FAIL_JSON = 'known_failures_%s.json' +def logfile_open(*args): + return open(*args, errors='replace') + + def generate_known_failures(testdir, overwrite, save, out): def collect_failures(results): success_index = 5 @@ -45,7 +47,7 @@ def collect_failures(results): if not r[success_index]: yield TestEntry.get_name(*r) try: - with logfile_open(path_join(testdir, RESULT_JSON), 'r') as fp: + with logfile_open(os.path.join(testdir, RESULT_JSON), 'r') as fp: results = json.load(fp) except IOError: sys.stderr.write('Unable to load last result. Did you run tests ?\n') @@ -68,7 +70,7 @@ def collect_failures(results): def load_known_failures(testdir): try: - with logfile_open(path_join(testdir, FAIL_JSON % platform.system()), 'r') as fp: + with logfile_open(os.path.join(testdir, FAIL_JSON % platform.system()), 'r') as fp: return json.load(fp) except IOError: return [] @@ -85,8 +87,8 @@ def __init__(self): @classmethod def test_logfile(cls, test_name, prog_kind, dir=None): - relpath = path_join('log', '%s_%s.log' % (test_name, prog_kind)) - return relpath if not dir else os.path.realpath(path_join(dir, relpath)) + relpath = os.path.join('log', '%s_%s.log' % (test_name, prog_kind)) + return relpath if not dir else os.path.realpath(os.path.join(dir, relpath)) def _start(self): self._start_time = time.time() @@ -200,7 +202,7 @@ def _close(self): def _print_header(self): self._print_date() - print('Executing: %s' % str_join(' ', self._prog.command), file=self.out) + print('Executing: %s' % ' '.join(self._prog.command), file=self.out) print('Directory: %s' % self._prog.workdir, file=self.out) print('config:delay: %s' % self._test.delay, file=self.out) print('config:timeout: %s' % self._test.timeout, file=self.out) @@ -222,8 +224,8 @@ def __init__(self, basedir, testdir_relative, concurrent=True): super(SummaryReporter, self).__init__() self._basedir = basedir self._testdir_rel = testdir_relative - self.logdir = path_join(self.testdir, LOG_DIR) - self.out_path = path_join(self.testdir, RESULT_JSON) + self.logdir = os.path.join(self.testdir, LOG_DIR) + self.out_path = os.path.join(self.testdir, RESULT_JSON) self.concurrent = concurrent self.out = sys.stdout self._platform = platform.system() @@ -240,7 +242,7 @@ def __init__(self, basedir, testdir_relative, concurrent=True): @property def testdir(self): - return path_join(self._basedir, self._testdir_rel) + return os.path.join(self._basedir, self._testdir_rel) def _result_string(self, test): if test.success: @@ -317,10 +319,7 @@ def _print_unexpected_success(self): self._print_bar() def _http_server_command(self, port): - if sys.version_info[0] < 3: - return 'python -m SimpleHTTPServer %d' % port - else: - return 'python -m http.server %d' % port + return 'python -m http.server %d' % port def _print_footer(self): fail_count = len(self._expected_failure) + len(self._unexpected_failure) diff --git a/test/crossrunner/run.py b/test/crossrunner/run.py index 126b7ec886a..3ccc6e32bd3 100644 --- a/test/crossrunner/run.py +++ b/test/crossrunner/run.py @@ -28,7 +28,6 @@ import sys import time -from .compat import str_join from .report import ExecReporter, SummaryReporter from .test import TestEntry from .util import domain_socket_path @@ -72,7 +71,7 @@ def _popen_args(self): return args def start(self): - joined = str_join(' ', self.cmd) + joined = ' '.join(self.cmd) self._log.debug('COMMAND: %s', joined) self._log.debug('WORKDIR: %s', self.cwd) self._log.debug('LOGFILE: %s', self.report.logpath) diff --git a/test/crossrunner/test.py b/test/crossrunner/test.py index 0e912843ab7..2a1a4da7c48 100644 --- a/test/crossrunner/test.py +++ b/test/crossrunner/test.py @@ -21,7 +21,6 @@ import multiprocessing import os import sys -from .compat import path_join from .util import merge_dict, domain_socket_path @@ -50,7 +49,7 @@ def __init__(self, kind, name, protocol, transport, socket, workdir, stop_signal def _fix_cmd_path(self, cmd): # if the arg is a file in the current directory, make it path def abs_if_exists(arg): - p = path_join(self.workdir, arg) + p = os.path.join(self.workdir, arg) return p if os.path.exists(p) else arg if cmd[0] == 'python': @@ -125,7 +124,7 @@ def _fix_workdir(self, config): if os.path.isabs(path): path = os.path.realpath(path) else: - path = os.path.realpath(path_join(self.testdir, path)) + path = os.path.realpath(os.path.join(self.testdir, path)) config.update({key: path}) return config diff --git a/test/dart/Makefile.am b/test/dart/Makefile.am index 81f2f5b1088..3552668f3d8 100644 --- a/test/dart/Makefile.am +++ b/test/dart/Makefile.am @@ -48,5 +48,8 @@ dist-hook: client: stubs ${DART} test_client/bin/main.dart +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ test_client diff --git a/test/dart/test_client/pubspec.yaml b/test/dart/test_client/pubspec.yaml index 177e2cdf141..0df6caea19f 100644 --- a/test/dart/test_client/pubspec.yaml +++ b/test/dart/test_client/pubspec.yaml @@ -16,7 +16,7 @@ # under the License. name: thrift_test_client -version: 0.20.0 +version: 0.22.0 description: A client integration test for the Dart Thrift library author: Apache Thrift Developers homepage: http://thrift.apache.org diff --git a/test/erl/Makefile.am b/test/erl/Makefile.am index 5bc90fa8814..665cb7ba051 100644 --- a/test/erl/Makefile.am +++ b/test/erl/Makefile.am @@ -40,6 +40,9 @@ clean: $(RM) -r .rebar/ $(RM) -r src/gen-erl/ +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + dist-hook: $(RM) $(distdir)/.generated $(RM) -r $(distdir)/.rebar/ diff --git a/test/erl/src/thrift_test.app.src b/test/erl/src/thrift_test.app.src index 9d68a564533..fa95d3c1e71 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.20.0"}, + {vsn, "0.22.0"}, % All modules used by the application. {modules, [ diff --git a/test/features/Makefile.am b/test/features/Makefile.am index 337d78950ef..4ee56f016fb 100644 --- a/test/features/Makefile.am +++ b/test/features/Makefile.am @@ -14,6 +14,9 @@ # under the License. # +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ local_thrift \ index.html \ diff --git a/test/go/Makefile.am b/test/go/Makefile.am index 92ddc93c955..a00fc379431 100644 --- a/test/go/Makefile.am +++ b/test/go/Makefile.am @@ -60,6 +60,9 @@ check: gopath genmock genmock: gopath sh genmock.sh +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ src/bin \ src/common \ diff --git a/test/go/go.mod b/test/go/go.mod index f69cdb4438e..d259db6530c 100644 --- a/test/go/go.mod +++ b/test/go/go.mod @@ -1,6 +1,6 @@ module github.com/apache/thrift/test/go -go 1.21 +go 1.23 require ( github.com/apache/thrift v0.0.0-00010101000000-000000000000 diff --git a/test/go/src/bin/stress/main.go b/test/go/src/bin/stress/main.go index 3273d1bbe2d..89e87c4a64c 100644 --- a/test/go/src/bin/stress/main.go +++ b/test/go/src/bin/stress/main.go @@ -133,7 +133,7 @@ func main() { if *clients != 0 { ready.Add(*clients + 1) done.Add(*clients) - for i := 0; i < *clients; i++ { + for range *clients { go client(protocolFactory) } ready.Done() @@ -170,45 +170,45 @@ func client(protocolFactory thrift.TProtocolFactory) { ready.Wait() switch callType { case echoVoid: - for i := 0; i < *loop; i++ { + for range *loop { client.EchoVoid(ctx) atomic.AddInt64(&clicounter, 1) } case echoByte: - for i := 0; i < *loop; i++ { + for range *loop { client.EchoByte(ctx, 42) atomic.AddInt64(&clicounter, 1) } case echoI32: - for i := 0; i < *loop; i++ { + for range *loop { client.EchoI32(ctx, 4242) atomic.AddInt64(&clicounter, 1) } case echoI64: - for i := 0; i < *loop; i++ { + for range *loop { client.EchoI64(ctx, 424242) atomic.AddInt64(&clicounter, 1) } case echoString: - for i := 0; i < *loop; i++ { + for range *loop { client.EchoString(ctx, "TestString") atomic.AddInt64(&clicounter, 1) } case echiList: l := []int8{-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8} - for i := 0; i < *loop; i++ { + for range *loop { client.EchoList(ctx, l) atomic.AddInt64(&clicounter, 1) } case echoSet: s := []int8{-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8} - for i := 0; i < *loop; i++ { + for range *loop { client.EchoSet(ctx, s) atomic.AddInt64(&clicounter, 1) } case echoMap: m := map[int8]int8{-10: 10, -9: 9, -8: 8, -7: 7, -6: 6, -5: 5, -4: 4, -3: 3, -2: 2, -1: 1, 0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8} - for i := 0; i < *loop; i++ { + for range *loop { client.EchoMap(ctx, m) atomic.AddInt64(&clicounter, 1) } diff --git a/test/go/src/bin/testclient/main.go b/test/go/src/bin/testclient/main.go index 95fcd47cc72..a71223ca602 100644 --- a/test/go/src/bin/testclient/main.go +++ b/test/go/src/bin/testclient/main.go @@ -20,8 +20,10 @@ package main import ( + "bytes" "context" "flag" + "fmt" t "log" "reflect" @@ -41,11 +43,15 @@ var testloops = flag.Int("testloops", 1, "Number of Tests") func main() { flag.Parse() - client, _, err := common.StartClient(*host, *port, *domain_socket, *transport, *protocol, *ssl) + addr := *domain_socket + if addr == "" { + addr = fmt.Sprintf("%s:%d", *host, *port) + } + client, _, err := common.StartClient(addr, *transport, *protocol, *ssl) if err != nil { t.Fatalf("Unable to start client: ", err) } - for i := 0; i < *testloops; i++ { + for range *testloops { callEverything(client) } } @@ -127,17 +133,15 @@ func callEverything(client *thrifttest.ThriftTestClient) { } binout := make([]byte, 256) - for i := 0; i < 256; i++ { + for i := range binout { binout[i] = byte(i) } bin, err := client.TestBinary(defaultCtx, binout) if err != nil { t.Fatalf("TestBinary failed with %v", err) } - for i := 0; i < 256; i++ { - if binout[i] != bin[i] { - t.Fatalf("Unexpected TestBinary() result expected %d, got %d ", binout[i], bin[i]) - } + if !bytes.Equal(binout, bin) { + t.Fatalf("Unexpected TestBinary() result expected % 02x, got % 02x ", binout, bin) } uout := thrift.Tuuid{ diff --git a/test/go/src/bin/testserver/main.go b/test/go/src/bin/testserver/main.go index 60a764fdbc8..0cfb62c9665 100644 --- a/test/go/src/bin/testserver/main.go +++ b/test/go/src/bin/testserver/main.go @@ -41,7 +41,7 @@ var certPath = flag.String("certPath", "keys", "Directory that contains SSL cert func main() { flag.Parse() - processor, serverTransport, transportFactory, protocolFactory, err := common.GetServerParams(*host, *port, *domain_socket, *transport, *protocol, *ssl, *certPath, common.PrintingHandler) + processor, serverTransport, transportFactory, protocolFactory, _, err := common.GetServerParams(*host, *port, *domain_socket, *transport, *protocol, *ssl, *certPath, common.PrintingHandler) if err != nil { log.Fatalf("Unable to process server params: %v", err) @@ -59,7 +59,10 @@ func main() { return } } else { - http.ListenAndServe(fmt.Sprintf(":%d", *port), nil) + if err := http.ListenAndServe(fmt.Sprintf(":%d", *port), nil); err != nil { + fmt.Println(err) + return + } } } else { server := thrift.NewTSimpleServer4(processor, serverTransport, transportFactory, protocolFactory) diff --git a/test/go/src/common/client.go b/test/go/src/common/client.go index f9dfcaf6bb7..2383b82e6c2 100644 --- a/test/go/src/common/client.go +++ b/test/go/src/common/client.go @@ -37,14 +37,11 @@ func init() { } func StartClient( - host string, - port int64, - domain_socket string, + addr string, transport string, protocol string, ssl bool, ) (client *thrifttest.ThriftTestClient, trans thrift.TTransport, err error) { - hostPort := fmt.Sprintf("%s:%d", host, port) cfg := &thrift.TConfiguration{ TLSConfig: &tls.Config{ InsecureSkipVerify: true, @@ -70,13 +67,9 @@ func StartClient( protocolFactory = thrift.NewTDebugProtocolFactoryWithLogger(protocolFactory, "client:", thrift.StdLogger(nil)) } if ssl { - trans = thrift.NewTSSLSocketConf(hostPort, cfg) + trans = thrift.NewTSSLSocketConf(addr, cfg) } else { - if domain_socket != "" { - trans = thrift.NewTSocketConf(domain_socket, nil) - } else { - trans = thrift.NewTSocketConf(hostPort, nil) - } + trans = thrift.NewTSocketConf(addr, nil) } if err != nil { return nil, nil, err @@ -88,10 +81,9 @@ func StartClient( TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, } client := &http.Client{Transport: tr} - trans, err = thrift.NewTHttpClientWithOptions(fmt.Sprintf("https://%s/", hostPort), thrift.THttpClientOptions{Client: client}) - fmt.Println(hostPort) + trans, err = thrift.NewTHttpClientWithOptions(fmt.Sprintf("https://%s/", addr), thrift.THttpClientOptions{Client: client}) } else { - trans, err = thrift.NewTHttpClient(fmt.Sprintf("http://%s/", hostPort)) + trans, err = thrift.NewTHttpClient(fmt.Sprintf("http://%s/", addr)) } case "framed": trans = thrift.NewTFramedTransportConf(trans, cfg) diff --git a/test/go/src/common/clientserver_test.go b/test/go/src/common/clientserver_test.go index a39519d8a56..48203b6739a 100644 --- a/test/go/src/common/clientserver_test.go +++ b/test/go/src/common/clientserver_test.go @@ -22,6 +22,7 @@ package common import ( "context" "errors" + "fmt" "reflect" "sync" "testing" @@ -42,10 +43,10 @@ type test_unit struct { } var units = []test_unit{ - {"127.0.0.1", 9095, "", "", "binary", false}, - {"127.0.0.1", 9091, "", "", "compact", false}, - {"127.0.0.1", 9092, "", "", "binary", true}, - {"127.0.0.1", 9093, "", "", "compact", true}, + {"127.0.0.1", 0, "", "", "binary", false}, + {"127.0.0.1", 0, "", "", "compact", false}, + {"127.0.0.1", 0, "", "", "binary", true}, + {"127.0.0.1", 0, "", "", "compact", true}, } func TestAllConnection(t *testing.T) { @@ -61,29 +62,31 @@ func TestAllConnection(t *testing.T) { } func doUnit(t *testing.T, unit *test_unit) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - handler := NewMockThriftTest(ctrl) - - processor, serverTransport, transportFactory, protocolFactory, err := GetServerParams(unit.host, unit.port, unit.domain_socket, unit.transport, unit.protocol, unit.ssl, "../../../keys", handler) - if err != nil { - t.Errorf("GetServerParams failed: %v", err) - } + t.Run(fmt.Sprintf("%v", *unit), func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + handler := NewMockThriftTest(ctrl) + + processor, serverTransport, transportFactory, protocolFactory, addr, err := GetServerParams(unit.host, unit.port, unit.domain_socket, unit.transport, unit.protocol, unit.ssl, "../../../keys", handler) + if err != nil { + t.Errorf("GetServerParams failed: %v", err) + } - server := thrift.NewTSimpleServer4(processor, serverTransport, transportFactory, protocolFactory) - if err = server.Listen(); err != nil { - t.Errorf("Unable to start server: %v", err) - return - } - go server.Serve() - defer server.Stop() - client, trans, err := StartClient(unit.host, unit.port, unit.domain_socket, unit.transport, unit.protocol, unit.ssl) - if err != nil { - t.Errorf("Unable to start client: %v", err) - return - } - defer trans.Close() - callEverythingWithMock(t, client, handler) + server := thrift.NewTSimpleServer4(processor, serverTransport, transportFactory, protocolFactory) + if err = server.Listen(); err != nil { + t.Errorf("Unable to start server: %v", err) + return + } + go server.Serve() + defer server.Stop() + client, trans, err := StartClient(addr, unit.transport, unit.protocol, unit.ssl) + if err != nil { + t.Errorf("Unable to start client: %v", err) + return + } + defer trans.Close() + callEverythingWithMock(t, client, handler) + }) } var rmapmap = map[int32]map[int32]int32{ diff --git a/test/go/src/common/context_test.go b/test/go/src/common/context_test.go index c6cbad8f68d..0aa217f5862 100644 --- a/test/go/src/common/context_test.go +++ b/test/go/src/common/context_test.go @@ -40,12 +40,17 @@ func (slowHttpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { } func TestHttpContextTimeout(t *testing.T) { - unit := test_unit{"127.0.0.1", 9096, "", "http", "binary", false} + const ( + host = "127.0.0.1" + port = 9096 + ) + addr := fmt.Sprintf("%s:%d", host, port) + unit := test_unit{host, port, "", "http", "binary", false} - server := &http.Server{Addr: unit.host + fmt.Sprintf(":%d", unit.port), Handler: slowHttpHandler{}} + server := &http.Server{Addr: addr, Handler: slowHttpHandler{}} go server.ListenAndServe() - client, trans, err := StartClient(unit.host, unit.port, unit.domain_socket, unit.transport, unit.protocol, unit.ssl) + client, trans, err := StartClient(addr, unit.transport, unit.protocol, unit.ssl) if err != nil { t.Errorf("Unable to start client: %v", err) return diff --git a/test/go/src/common/server.go b/test/go/src/common/server.go index f48389d4406..85429f0a6b5 100644 --- a/test/go/src/common/server.go +++ b/test/go/src/common/server.go @@ -46,7 +46,7 @@ func GetServerParams( ssl bool, certPath string, handler thrifttest.ThriftTest, -) (thrift.TProcessor, thrift.TServerTransport, thrift.TTransportFactory, thrift.TProtocolFactory, error) { +) (thrift.TProcessor, thrift.TServerTransport, thrift.TTransportFactory, thrift.TProtocolFactory, string /* addr */, error) { var err error hostPort := fmt.Sprintf("%s:%d", host, port) @@ -65,30 +65,67 @@ func GetServerParams( case "header": protocolFactory = thrift.NewTHeaderProtocolFactoryConf(nil) default: - return nil, nil, nil, nil, fmt.Errorf("invalid protocol specified %s", protocol) + return nil, nil, nil, nil, "", fmt.Errorf("invalid protocol specified %s", protocol) } if debugServerProtocol { protocolFactory = thrift.NewTDebugProtocolFactoryWithLogger(protocolFactory, "server:", thrift.StdLogger(nil)) } var serverTransport thrift.TServerTransport + var addr string + if transport == "http" { + // In cross-test servers, we would call http.ListenAndServe + // again on the host:port, so don't use the listen to fill the + // addr and just generate it here instead. + addr = hostPort + if domain_socket != "" { + addr = domain_socket + } + } if ssl { cfg := new(tls.Config) if cert, err := tls.LoadX509KeyPair(certPath+"/server.crt", certPath+"/server.key"); err != nil { - return nil, nil, nil, nil, err + return nil, nil, nil, nil, "", err } else { cfg.Certificates = append(cfg.Certificates, cert) } - serverTransport, err = thrift.NewTSSLServerSocket(hostPort, cfg) + serverSocket, transportErr := thrift.NewTSSLServerSocket(hostPort, cfg) + if transportErr == nil { + if transport != "http" { + listenErr := serverSocket.Listen() + if listenErr == nil { + serverTransport = serverSocket + addr = serverSocket.Addr().String() + } else { + err = listenErr + } + } + } else { + err = transportErr + } } else { if domain_socket != "" { serverTransport, err = thrift.NewTServerSocket(domain_socket) + addr = domain_socket } else { - serverTransport, err = thrift.NewTServerSocket(hostPort) + serverSocket, transportErr := thrift.NewTServerSocket(hostPort) + if transportErr == nil { + if transport != "http" { + listenErr := serverSocket.Listen() + if listenErr == nil { + serverTransport = serverSocket + addr = serverSocket.Addr().String() + } else { + err = listenErr + } + } + } else { + err = transportErr + } } } if err != nil { - return nil, nil, nil, nil, err + return nil, nil, nil, nil, "", err } var transportFactory thrift.TTransportFactory @@ -107,9 +144,9 @@ func GetServerParams( case "": transportFactory = thrift.NewTTransportFactory() default: - return nil, nil, nil, nil, fmt.Errorf("invalid transport specified %s", transport) + return nil, nil, nil, nil, "", fmt.Errorf("invalid transport specified %s", transport) } processor := thrifttest.NewThriftTestProcessor(handler) - return processor, serverTransport, transportFactory, protocolFactory, nil + return processor, serverTransport, transportFactory, protocolFactory, addr, nil } diff --git a/test/haxe/Makefile.am b/test/haxe/Makefile.am index d37aaa77aca..6274f29bf4e 100644 --- a/test/haxe/Makefile.am +++ b/test/haxe/Makefile.am @@ -84,6 +84,9 @@ check_php_web: $(BIN_PHP_WEB) $(BIN_CPP) sleep 10 +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ src \ cpp.hxml \ diff --git a/test/lua/Makefile.am b/test/lua/Makefile.am index a3ab3e26ad3..7cdbe048f31 100644 --- a/test/lua/Makefile.am +++ b/test/lua/Makefile.am @@ -19,16 +19,16 @@ THRIFT = $(top_builddir)/compiler/cpp/thrift -# Remove "MapType =" line to ignore some map bug for now -stubs: ../v0.16/ThriftTest.thrift $(THRIFT) - $(THRIFT) --gen lua $< - $(SED) -i.bak 's/MapType =//g' gen-lua/ThriftTest_ttypes.lua - $(RM) gen-lua/ThriftTest_ttypes.lua.bak +stubs: ../ThriftTest.thrift + $(THRIFT) --gen lua ../ThriftTest.thrift precross: stubs clean-local: $(RM) -r gen-lua/ +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + dist-hook: $(RM) -r $(distdir)/gen-lua/ diff --git a/test/lua/test_basic_client.lua b/test/lua/test_basic_client.lua index 11567d906b3..1932dd8c157 100644 --- a/test/lua/test_basic_client.lua +++ b/test/lua/test_basic_client.lua @@ -24,7 +24,7 @@ require('TCompactProtocol') require('TJsonProtocol') require('TBinaryProtocol') require('ThriftTest_ThriftTest') -require('liblualongnumber') +local liblualongnumber = require('liblualongnumber') local client @@ -98,6 +98,9 @@ function testBasicClient(rawArgs) assertEqual(client:testString('lala'), 'lala', 'Failed testString') assertEqual(client:testString('wahoo'), 'wahoo', 'Failed testString') + -- UUID + assertEqual(client:testUuid(TUUIDfromString('00112233-4455-6677-8899-aabbccddeeff')):getString(), '00112233-4455-6677-8899-aabbccddeeff', 'Failed testUuid') + -- Bool assertEqual(client:testBool(true), true, 'Failed testBool true') assertEqual(client:testBool(false), false, 'Failed testBool false') diff --git a/test/lua/test_basic_server.lua b/test/lua/test_basic_server.lua index 20ac407c8da..0b421d1ed91 100644 --- a/test/lua/test_basic_server.lua +++ b/test/lua/test_basic_server.lua @@ -24,7 +24,7 @@ require('TCompactProtocol') require('TJsonProtocol') require('TBinaryProtocol') require('TServer') -require('liblualongnumber') +local liblualongnumber = require('liblualongnumber') -------------------------------------------------------------------------------- -- Handler @@ -62,10 +62,113 @@ function TestHandler:testBinary(by) return by end +function TestHandler:testUuid(uuid) + return uuid +end + +function TestHandler:testNest(thing) + return thing +end + function TestHandler:testStruct(thing) return thing end +function TestHandler:testMap(thing) + return thing +end + +function TestHandler:testStringMap(thing) + return thing +end + +function TestHandler:testSet(thing) + return thing +end + +function TestHandler:testList(thing) + return thing +end + +function TestHandler:testEnum(thing) + return thing +end + +function TestHandler:testTypedef(thing) + return thing +end + +function TestHandler:testMapMap(hello) + return { + ["-4"] = { + ["-4"] = -4, + ["-3"] = -3, + ["-2"] = -2, + ["-1"] = -1 + }, + ["4"] = { + ["1"] = 1, + ["2"] = 2, + ["3"] = 3, + ["4"] = 4 + } + } +end + +function TestHandler:testInsanity(argument) + local first_map = { + [Numberz.TWO] = argument, + [Numberz.THREE] = argument + }; + local second_map = { + [Numberz.SIX] = Insanity:new { + userMap = {}, + xtructs = {} + } + } + + return { + ["1"] = first_map, + ["2"] = second_map + }; +end + +function TestHandler:testMulti(arg0, arg1, arg2, arg3, arg4, arg5) + return Xtruct:new {} +end + +function TestHandler:testException(arg) + if arg == "Xception" then + return Xception:new { + errorCode = 1001, + message = arg + } + elseif arg == "TException" then + error("") + end +end + +function TestHandler:testMultiException(arg0, arg1) + if arg0 == "Xception" then + return Xception:new { + errorCode = 1001, + message = "This is an Xception" + } + elseif arg0 == "Xception2" then + return Xception2:new { + errorCode = 2002, + struct_thing = Xtruct:new { + string_thing = "This is an Xception2" + } + } + elseif arg0 == "TException" then + error("") + end + return Xtruct:new { + string_thing = arg1 + } +end + function TestHandler:testOneway(secondsToSleep) print("testOneway secondsToSleep:", secondsToSleep) end diff --git a/test/netstd/Client/Client.csproj b/test/netstd/Client/Client.csproj index aa90e2c5ec7..d9f61f8eee4 100644 --- a/test/netstd/Client/Client.csproj +++ b/test/netstd/Client/Client.csproj @@ -19,12 +19,12 @@ --> - net8.0 + net9.0 latestMajor Client Client Exe - 0.20.0.0 + 0.22.0.0 false false false @@ -35,9 +35,9 @@ - + - + @@ -49,8 +49,8 @@ - - - + + + diff --git a/test/netstd/Client/TestClient.cs b/test/netstd/Client/TestClient.cs index 74867122951..26bd120c46f 100644 --- a/test/netstd/Client/TestClient.cs +++ b/test/netstd/Client/TestClient.cs @@ -225,7 +225,8 @@ private static X509Certificate2 GetClientCert() throw new FileNotFoundException($"Cannot find file: {clientCertName}"); } - var cert = new X509Certificate2(existingPath, "thrift"); + //var cert = new X509Certificate2(existingPath, "thrift"); + var cert = X509CertificateLoader.LoadPkcs12FromFile(existingPath, "thrift"); return cert; } @@ -444,7 +445,7 @@ public static Task Execute(List args) public static string BytesToHex(byte[] data) { - return BitConverter.ToString(data).Replace("-", string.Empty); + return Convert.ToHexString(data); } diff --git a/test/netstd/Makefile.am b/test/netstd/Makefile.am index 9712fc2a431..bd06cd4b496 100644 --- a/test/netstd/Makefile.am +++ b/test/netstd/Makefile.am @@ -32,6 +32,9 @@ clean-local: $(RM) -r Server/obj $(RM) -r ThriftTest/ThriftTest +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ Client \ README.md \ diff --git a/test/netstd/Server/Server.csproj b/test/netstd/Server/Server.csproj index 63ce613bbda..130b466f99d 100644 --- a/test/netstd/Server/Server.csproj +++ b/test/netstd/Server/Server.csproj @@ -19,12 +19,12 @@ --> - net8.0 + net9.0 latestMajor Server Server Exe - 0.20.0.0 + 0.22.0.0 false false false @@ -36,9 +36,9 @@ - + - + @@ -50,8 +50,8 @@ - - - + + + diff --git a/test/netstd/Server/TestServer.cs b/test/netstd/Server/TestServer.cs index 2dea4182477..54654c85967 100644 --- a/test/netstd/Server/TestServer.cs +++ b/test/netstd/Server/TestServer.cs @@ -37,6 +37,7 @@ #pragma warning disable IDE0063 // using can be simplified, we don't #pragma warning disable IDE0057 // substr can be simplified, we don't +#pragma warning disable IDE0130 // unexpected folder structure namespace ThriftTest { @@ -554,9 +555,10 @@ private static X509Certificate2 GetServerCert() { throw new FileNotFoundException($"Cannot find file: {serverCertName}"); } - - var cert = new X509Certificate2(existingPath, "thrift"); - + + //var cert = new X509Certificate2(existingPath, "thrift"); + var cert = X509CertificateLoader.LoadPkcs12FromFile(existingPath, "thrift"); + return cert; } diff --git a/test/netstd/ThriftTest.sln b/test/netstd/ThriftTest.sln index 7e101d9e0e1..45bc1f01c4c 100644 --- a/test/netstd/ThriftTest.sln +++ b/test/netstd/ThriftTest.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.30104.148 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.32112.339 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Thrift", "..\..\lib\netstd\Thrift\Thrift.csproj", "{C20EA2A9-7660-47DE-9A49-D1EF12FB2895}" EndProject @@ -11,12 +11,16 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Server", "Server\Server.csp EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Thrift.IntegrationTests", "..\..\lib\netstd\Tests\Thrift.IntegrationTests\Thrift.IntegrationTests.csproj", "{C8148BFF-B943-4474-8D33-A641C6FD3DAB}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Thrift.PublicInterfaces.Compile.Tests", "..\..\lib\netstd\Tests\Thrift.PublicInterfaces.Compile.Tests\Thrift.PublicInterfaces.Compile.Tests.csproj", "{5D86C1B6-0CDA-4D1D-80A5-240583B21148}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Thrift.Tests", "..\..\lib\netstd\Tests\Thrift.Tests\Thrift.Tests.csproj", "{37FDED71-F8FB-434B-B2A8-1C53CCD9FD38}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Thrift.Benchmarks", "..\..\lib\netstd\Benchmarks\Thrift.Benchmarks\Thrift.Benchmarks.csproj", "{66946544-8DE7-45E9-8D0E-93EADA028D44}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Thrift.Compile.net8", "..\..\lib\netstd\Tests\Thrift.Compile.Tests\Thrift.Compile.net8\Thrift.Compile.net8.csproj", "{05FAA75C-06BE-462F-999F-63823D08C75A}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Thrift.Compile.netstd2", "..\..\lib\netstd\Tests\Thrift.Compile.Tests\Thrift.Compile.netstd2\Thrift.Compile.netstd2.csproj", "{F27E60D2-23D3-4946-BB6C-A809EDBEFE2C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Thrift.Compile.net9", "..\..\lib\netstd\Tests\Thrift.Compile.Tests\Thrift.Compile.net9\Thrift.Compile.net9.csproj", "{BB512CA7-D013-4CDC-AD2B-1E5EA121ED59}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -75,18 +79,6 @@ Global {C8148BFF-B943-4474-8D33-A641C6FD3DAB}.Release|x64.Build.0 = Release|Any CPU {C8148BFF-B943-4474-8D33-A641C6FD3DAB}.Release|x86.ActiveCfg = Release|Any CPU {C8148BFF-B943-4474-8D33-A641C6FD3DAB}.Release|x86.Build.0 = Release|Any CPU - {5D86C1B6-0CDA-4D1D-80A5-240583B21148}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5D86C1B6-0CDA-4D1D-80A5-240583B21148}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5D86C1B6-0CDA-4D1D-80A5-240583B21148}.Debug|x64.ActiveCfg = Debug|Any CPU - {5D86C1B6-0CDA-4D1D-80A5-240583B21148}.Debug|x64.Build.0 = Debug|Any CPU - {5D86C1B6-0CDA-4D1D-80A5-240583B21148}.Debug|x86.ActiveCfg = Debug|Any CPU - {5D86C1B6-0CDA-4D1D-80A5-240583B21148}.Debug|x86.Build.0 = Debug|Any CPU - {5D86C1B6-0CDA-4D1D-80A5-240583B21148}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5D86C1B6-0CDA-4D1D-80A5-240583B21148}.Release|Any CPU.Build.0 = Release|Any CPU - {5D86C1B6-0CDA-4D1D-80A5-240583B21148}.Release|x64.ActiveCfg = Release|Any CPU - {5D86C1B6-0CDA-4D1D-80A5-240583B21148}.Release|x64.Build.0 = Release|Any CPU - {5D86C1B6-0CDA-4D1D-80A5-240583B21148}.Release|x86.ActiveCfg = Release|Any CPU - {5D86C1B6-0CDA-4D1D-80A5-240583B21148}.Release|x86.Build.0 = Release|Any CPU {37FDED71-F8FB-434B-B2A8-1C53CCD9FD38}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {37FDED71-F8FB-434B-B2A8-1C53CCD9FD38}.Debug|Any CPU.Build.0 = Debug|Any CPU {37FDED71-F8FB-434B-B2A8-1C53CCD9FD38}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -111,6 +103,42 @@ Global {66946544-8DE7-45E9-8D0E-93EADA028D44}.Release|x64.Build.0 = Release|Any CPU {66946544-8DE7-45E9-8D0E-93EADA028D44}.Release|x86.ActiveCfg = Release|Any CPU {66946544-8DE7-45E9-8D0E-93EADA028D44}.Release|x86.Build.0 = Release|Any CPU + {05FAA75C-06BE-462F-999F-63823D08C75A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {05FAA75C-06BE-462F-999F-63823D08C75A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {05FAA75C-06BE-462F-999F-63823D08C75A}.Debug|x64.ActiveCfg = Debug|Any CPU + {05FAA75C-06BE-462F-999F-63823D08C75A}.Debug|x64.Build.0 = Debug|Any CPU + {05FAA75C-06BE-462F-999F-63823D08C75A}.Debug|x86.ActiveCfg = Debug|Any CPU + {05FAA75C-06BE-462F-999F-63823D08C75A}.Debug|x86.Build.0 = Debug|Any CPU + {05FAA75C-06BE-462F-999F-63823D08C75A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {05FAA75C-06BE-462F-999F-63823D08C75A}.Release|Any CPU.Build.0 = Release|Any CPU + {05FAA75C-06BE-462F-999F-63823D08C75A}.Release|x64.ActiveCfg = Release|Any CPU + {05FAA75C-06BE-462F-999F-63823D08C75A}.Release|x64.Build.0 = Release|Any CPU + {05FAA75C-06BE-462F-999F-63823D08C75A}.Release|x86.ActiveCfg = Release|Any CPU + {05FAA75C-06BE-462F-999F-63823D08C75A}.Release|x86.Build.0 = Release|Any CPU + {F27E60D2-23D3-4946-BB6C-A809EDBEFE2C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F27E60D2-23D3-4946-BB6C-A809EDBEFE2C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F27E60D2-23D3-4946-BB6C-A809EDBEFE2C}.Debug|x64.ActiveCfg = Debug|Any CPU + {F27E60D2-23D3-4946-BB6C-A809EDBEFE2C}.Debug|x64.Build.0 = Debug|Any CPU + {F27E60D2-23D3-4946-BB6C-A809EDBEFE2C}.Debug|x86.ActiveCfg = Debug|Any CPU + {F27E60D2-23D3-4946-BB6C-A809EDBEFE2C}.Debug|x86.Build.0 = Debug|Any CPU + {F27E60D2-23D3-4946-BB6C-A809EDBEFE2C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F27E60D2-23D3-4946-BB6C-A809EDBEFE2C}.Release|Any CPU.Build.0 = Release|Any CPU + {F27E60D2-23D3-4946-BB6C-A809EDBEFE2C}.Release|x64.ActiveCfg = Release|Any CPU + {F27E60D2-23D3-4946-BB6C-A809EDBEFE2C}.Release|x64.Build.0 = Release|Any CPU + {F27E60D2-23D3-4946-BB6C-A809EDBEFE2C}.Release|x86.ActiveCfg = Release|Any CPU + {F27E60D2-23D3-4946-BB6C-A809EDBEFE2C}.Release|x86.Build.0 = Release|Any CPU + {BB512CA7-D013-4CDC-AD2B-1E5EA121ED59}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BB512CA7-D013-4CDC-AD2B-1E5EA121ED59}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BB512CA7-D013-4CDC-AD2B-1E5EA121ED59}.Debug|x64.ActiveCfg = Debug|Any CPU + {BB512CA7-D013-4CDC-AD2B-1E5EA121ED59}.Debug|x64.Build.0 = Debug|Any CPU + {BB512CA7-D013-4CDC-AD2B-1E5EA121ED59}.Debug|x86.ActiveCfg = Debug|Any CPU + {BB512CA7-D013-4CDC-AD2B-1E5EA121ED59}.Debug|x86.Build.0 = Debug|Any CPU + {BB512CA7-D013-4CDC-AD2B-1E5EA121ED59}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BB512CA7-D013-4CDC-AD2B-1E5EA121ED59}.Release|Any CPU.Build.0 = Release|Any CPU + {BB512CA7-D013-4CDC-AD2B-1E5EA121ED59}.Release|x64.ActiveCfg = Release|Any CPU + {BB512CA7-D013-4CDC-AD2B-1E5EA121ED59}.Release|x64.Build.0 = Release|Any CPU + {BB512CA7-D013-4CDC-AD2B-1E5EA121ED59}.Release|x86.ActiveCfg = Release|Any CPU + {BB512CA7-D013-4CDC-AD2B-1E5EA121ED59}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/test/perl/Makefile.am b/test/perl/Makefile.am index 589fe624bf5..0064a6e7355 100644 --- a/test/perl/Makefile.am +++ b/test/perl/Makefile.am @@ -27,5 +27,8 @@ check: stubs clean-local: $(RM) -r gen-perl/ +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + dist-hook: $(RM) -r $(distdir)/gen-perl/ diff --git a/test/php/Client.php b/test/php/Client.php new file mode 100644 index 00000000000..1cd424126e1 --- /dev/null +++ b/test/php/Client.php @@ -0,0 +1,26 @@ +registerDefinition('ThriftTest', __DIR__ . '/../../lib/php/test/Resources/packages/phpcm'); +$loader->register(); + + +$transport = new THttpClient('localhost', 80); + +$transport->setTimeoutSecs($this->timeoutSec); + +$transport->addHeaders($this->generateAuthHeader()); + +$protocol = new TCompactProtocol($transport); + +$transport->open(); + +$client = new \ThriftTest\ThriftTestClient($protocol); +$client->testVoid(); diff --git a/test/php/Handler.php b/test/php/Handler.php new file mode 100644 index 00000000000..5ca06a21d03 --- /dev/null +++ b/test/php/Handler.php @@ -0,0 +1,114 @@ +registerDefinition('ThriftTest', __DIR__ . '/../../lib/php/test/Resources/packages/phpcm'); +$loader->register(); + +$sslOptions = \stream_context_create( + [ + 'ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + ], + ] +); + +require_once __DIR__ . '/Handler.php'; + +switch ($transport) { + case 'framed': + $serverTransportFactory = new \Thrift\Factory\TFramedTransportFactory(); + break; + default: + $serverTransportFactory = new \Thrift\Factory\TTransportFactory(); +} + +$serverTransport = new \Thrift\Server\TServerSocket('localhost', $port); +$handler = new Handler(); +$processor = new ThriftTest\ThriftTestProcessor($handler); + +$server = new \Thrift\Server\TSimpleServer( + $processor, + $serverTransport, + $serverTransportFactory, + $serverTransportFactory, + new \Thrift\Factory\TBinaryProtocolFactory(), + new \Thrift\Factory\TBinaryProtocolFactory() +); + +echo "Starting the Test server...\n"; +$server->serve(); diff --git a/test/php/test_php.ini b/test/php/test_php.ini index aeb67cbd411..5eecb329618 100644 --- a/test/php/test_php.ini +++ b/test/php/test_php.ini @@ -1,3 +1,3 @@ -extension=thrift_protocol.so -extension=json.so -extension=sockets.so +;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 3b78793f772..214ded2067d 100644 --- a/test/py.tornado/Makefile.am +++ b/test/py.tornado/Makefile.am @@ -32,6 +32,9 @@ clean-local: find . -type d \( -iname "__pycache__" -or -iname "_trial_temp" \) | xargs rm -rf $(RM) -r gen-py*/ +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + dist-hook: find $(distdir) -type f \( -iname "*.pyc" \) | xargs rm -f find $(distdir) -type d \( -iname "__pycache__" -or -iname "_trial_temp" \) | xargs rm -rf diff --git a/test/py.twisted/Makefile.am b/test/py.twisted/Makefile.am index bd0cdb1a45a..6461d12f13a 100644 --- a/test/py.twisted/Makefile.am +++ b/test/py.twisted/Makefile.am @@ -32,6 +32,9 @@ clean-local: find . -type d \( -iname "__pycache__" -or -iname "_trial_temp" \) | xargs rm -rf $(RM) -r gen-py*/ +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + dist-hook: find $(distdir) -type f \( -iname "*.pyc" \) | xargs rm -f find $(distdir) -type d \( -iname "__pycache__" -or -iname "_trial_temp" \) | xargs rm -rf diff --git a/test/py/FastbinaryTest.py b/test/py/FastbinaryTest.py index 05c0bb6d15a..f6803575cdb 100755 --- a/test/py/FastbinaryTest.py +++ b/test/py/FastbinaryTest.py @@ -25,8 +25,6 @@ # TODO(dreiss): Test error cases. Check for memory leaks. -from __future__ import print_function - import math import os import sys @@ -68,15 +66,11 @@ def isOpen(self): ooe2.integer64 = 64 ooe2.double_precision = (math.sqrt(5) + 1) / 2 ooe2.some_characters = ":R (me going \"rrrr\")" -ooe2.zomg_unicode = u"\xd3\x80\xe2\x85\xae\xce\x9d\x20"\ - u"\xd0\x9d\xce\xbf\xe2\x85\xbf\xd0\xbe"\ - u"\xc9\xa1\xd0\xb3\xd0\xb0\xcf\x81\xe2\x84\x8e"\ - u"\x20\xce\x91\x74\x74\xce\xb1\xe2\x85\xbd\xce\xba"\ - u"\xc7\x83\xe2\x80\xbc" - -if sys.version_info[0] == 2 and os.environ.get('THRIFT_TEST_PY_NO_UTF8STRINGS'): - ooe1.zomg_unicode = ooe1.zomg_unicode.encode('utf8') - ooe2.zomg_unicode = ooe2.zomg_unicode.encode('utf8') +ooe2.zomg_unicode = "\xd3\x80\xe2\x85\xae\xce\x9d\x20"\ + "\xd0\x9d\xce\xbf\xe2\x85\xbf\xd0\xbe"\ + "\xc9\xa1\xd0\xb3\xd0\xb0\xcf\x81\xe2\x84\x8e"\ + "\x20\xce\x91\x74\x74\xce\xb1\xe2\x85\xbd\xce\xba"\ + "\xc7\x83\xe2\x80\xbc" hm = HolyMoley(**{"big": [], "contain": set(), "bonks": {}}) hm.big.append(ooe1) @@ -86,10 +80,7 @@ def isOpen(self): hm.contain.add(("and a one", "and a two")) hm.contain.add(("then a one, two", "three!", "FOUR!")) -if sys.version_info[0] == 2 and os.environ.get('THRIFT_TEST_PY_NO_UTF8STRINGS'): - hm.contain.add((u"\xd7\n\a\t".encode('utf8'),)) -else: - hm.contain.add((u"\xd7\n\a\t",)) +hm.contain.add(("\xd7\n\a\t",)) hm.contain.add(()) hm.bonks["nothing"] = [] diff --git a/test/py/Makefile.am b/test/py/Makefile.am index 7c78f17da22..7e403d13dbd 100644 --- a/test/py/Makefile.am +++ b/test/py/Makefile.am @@ -52,8 +52,14 @@ thrift_gen = \ gen-py-enum/ThriftTest/__init__.py \ gen-py-enum/DebugProtoTest/__init__.py \ gen-py-enum/DoubleConstantsTest/__init__.py \ - gen-py-enum/Recursive/__init__.py + gen-py-enum/Recursive/__init__.py \ + gen-py-type_hints/ThriftTest/__init__.py \ + gen-py-type_hints/DebugProtoTest/__init__.py \ + gen-py-type_hints/DoubleConstantsTest/__init__.py \ + gen-py-type_hints/Recursive/__init__.py +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am precross: $(thrift_gen) BUILT_SOURCES = $(thrift_gen) @@ -117,6 +123,12 @@ gen-py-enum/%/__init__.py: ../%.thrift $(THRIFT) && $(THRIFT) --gen py:enum -out gen-py-enum ../v0.16/$(notdir $<) \ || $(THRIFT) --gen py:enum -out gen-py-enum $< +gen-py-type_hints/%/__init__.py: ../%.thrift $(THRIFT) + test -d gen-py-type_hints || $(MKDIR_P) gen-py-type_hints + test ../$(notdir $<) \ + && $(THRIFT) --gen py:type_hints,enum -out gen-py-type_hints ../$(notdir $<) \ + || $(THRIFT) --gen py:type_hints,enum -out gen-py-type_hints $< + clean-local: $(RM) -r build find . -type f \( -iname "*.pyc" \) | xargs rm -f diff --git a/test/py/RunClientServer.py b/test/py/RunClientServer.py index cb0decf0e57..f48224fa5cf 100755 --- a/test/py/RunClientServer.py +++ b/test/py/RunClientServer.py @@ -19,8 +19,6 @@ # under the License. # -from __future__ import division -from __future__ import print_function import platform import copy import os @@ -44,6 +42,7 @@ 'TestEof.py', 'TestSyntax.py', 'TestSocket.py', + 'TestTypes.py' ] FRAMED = ["TNonblockingServer"] SKIP_ZLIB = ['TNonblockingServer', 'THttpServer'] @@ -259,7 +258,7 @@ def main(): parser = OptionParser() parser.add_option('--all', action="store_true", dest='all') parser.add_option('--genpydirs', type='string', dest='genpydirs', - default='default,slots,oldstyle,no_utf8strings,dynamic,dynamicslots,enum', + default='default,slots,oldstyle,no_utf8strings,dynamic,dynamicslots,enum,type_hints', help='directory extensions for generated code, used as suffixes for \"gen-py-*\" added sys.path for individual tests') parser.add_option("--port", type="int", dest="port", default=9090, help="port number for server to listen on") diff --git a/test/py/SerializationTest.py b/test/py/SerializationTest.py index f47c3d4d6af..218f26c43be 100755 --- a/test/py/SerializationTest.py +++ b/test/py/SerializationTest.py @@ -278,9 +278,6 @@ def testCompactStruct(self): self.assertTrue(len(rep) > 0) def testIntegerLimits(self): - if (sys.version_info[0] == 2 and sys.version_info[1] <= 6): - print('Skipping testIntegerLimits for Python 2.6') - return bad_values = [CompactProtoTestStruct(a_byte=128), CompactProtoTestStruct(a_byte=-129), CompactProtoTestStruct(a_i16=32768), CompactProtoTestStruct(a_i16=-32769), CompactProtoTestStruct(a_i32=2147483648), CompactProtoTestStruct(a_i32=-2147483649), diff --git a/test/py/TestClient.py b/test/py/TestClient.py index 61a9c60404f..d80ddf46f70 100755 --- a/test/py/TestClient.py +++ b/test/py/TestClient.py @@ -106,9 +106,6 @@ def testString(self): Türkçe, Татарча/Tatarça, Українська, اردو, Tiếng Việt, Volapük, Walon, Winaray, 吴语, isiXhosa, ייִדיש, Yorùbá, Zeêuws, 中文, Bân-lâm-gú, 粵語""" - if sys.version_info[0] == 2 and os.environ.get('THRIFT_TEST_PY_NO_UTF8STRINGS'): - s1 = s1.encode('utf8') - s2 = s2.encode('utf8') self.assertEqual(self.client.testString(s1), s1) self.assertEqual(self.client.testString(s2), s2) diff --git a/test/py/TestServer.py b/test/py/TestServer.py index 81ae1ad62ee..e062378a8fa 100755 --- a/test/py/TestServer.py +++ b/test/py/TestServer.py @@ -18,7 +18,6 @@ # specific language governing permissions and limitations # under the License. # -from __future__ import division import logging import os import signal diff --git a/test/py/TestTypes.py b/test/py/TestTypes.py new file mode 100644 index 00000000000..f578f42e90c --- /dev/null +++ b/test/py/TestTypes.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python + +# +# 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. +from ThriftTest import ThriftTest +from ThriftTest.ThriftTest import Client +from ThriftTest.ttypes import Xtruct + +import unittest + +# only run this test if the string 'options string: py:type_hints' esxists in the file +def has_type_hints_option(): + with open(ThriftTest.__file__) as f: + return 'options string: py:type_hints' in f.read() + +@unittest.skipUnless(has_type_hints_option(), "type hints not enabled") +class TypeAnnotationsTest(unittest.TestCase): + + def test_void(self): + self.assertEqual(Client.testVoid.__annotations__, {'return': None}) + + def test_string(self): + self.assertEqual(Client.testString.__annotations__, {'return': str, 'thing': str}) + + def test_byte(self): + self.assertEqual(Client.testByte.__annotations__, {'return': int, 'thing': int}) + + def test_i32(self): + self.assertEqual(Client.testI32.__annotations__, {'return': int, 'thing': int}) + + def test_i64(self): + self.assertEqual(Client.testI64.__annotations__, {'return': int, 'thing': int}) + + def test_double(self): + self.assertEqual(Client.testDouble.__annotations__, {'return': float, 'thing': float}) + + def test_binary(self): + self.assertEqual(Client.testBinary.__annotations__, {'return': bytes, 'thing': bytes}) + + def test_struct(self): + self.assertEqual(Client.testStruct.__annotations__, {'return': Xtruct, 'thing': Xtruct}) + + def test_map(self): + self.assertEqual(Client.testMap.__annotations__, {'return': dict[int, int], 'thing': dict[int, int]}) + + def test_list(self): + self.assertEqual(Client.testList.__annotations__, {'return': list[int], 'thing': list[int]}) + + def test_set(self): + self.assertEqual(Client.testSet.__annotations__, {'return': set[int], 'thing': set[int]}) diff --git a/test/py/generate.cmake b/test/py/generate.cmake index eb6f1110624..80e7f515bab 100644 --- a/test/py/generate.cmake +++ b/test/py/generate.cmake @@ -14,6 +14,7 @@ generate(${MY_PROJECT_DIR}/test/v0.16/ThriftTest.thrift py:no_utf8strings gen-py generate(${MY_PROJECT_DIR}/test/v0.16/ThriftTest.thrift py:dynamic gen-py-dynamic) generate(${MY_PROJECT_DIR}/test/v0.16/ThriftTest.thrift py:dynamic,slots gen-py-dynamicslots) generate(${MY_PROJECT_DIR}/test/v0.16/ThriftTest.thrift py:enum gen-py-enum) +generate(${MY_PROJECT_DIR}/test/ThriftTest.thrift py:type_hints,enum gen-py-type_hints) generate(${MY_PROJECT_DIR}/test/v0.16/DebugProtoTest.thrift py gen-py-default) generate(${MY_PROJECT_DIR}/test/v0.16/DebugProtoTest.thrift py:slots gen-py-slots) @@ -22,6 +23,7 @@ generate(${MY_PROJECT_DIR}/test/v0.16/DebugProtoTest.thrift py:no_utf8strings ge generate(${MY_PROJECT_DIR}/test/v0.16/DebugProtoTest.thrift py:dynamic gen-py-dynamic) generate(${MY_PROJECT_DIR}/test/v0.16/DebugProtoTest.thrift py:dynamic,slots gen-py-dynamicslots) generate(${MY_PROJECT_DIR}/test/v0.16/DebugProtoTest.thrift py:enum gen-py-enum) +generate(${MY_PROJECT_DIR}/test/DebugProtoTest.thrift py:type_hints,enum gen-py-type_hints) generate(${MY_PROJECT_DIR}/test/DoubleConstantsTest.thrift py gen-py-default) generate(${MY_PROJECT_DIR}/test/DoubleConstantsTest.thrift py:slots gen-py-slots) @@ -30,6 +32,7 @@ generate(${MY_PROJECT_DIR}/test/DoubleConstantsTest.thrift py:no_utf8strings gen generate(${MY_PROJECT_DIR}/test/DoubleConstantsTest.thrift py:dynamic gen-py-dynamic) generate(${MY_PROJECT_DIR}/test/DoubleConstantsTest.thrift py:dynamic,slots gen-py-dynamicslots) generate(${MY_PROJECT_DIR}/test/DoubleConstantsTest.thrift py:enum gen-py-enum) +generate(${MY_PROJECT_DIR}/test/DoubleConstantsTest.thrift py:type_hints,enum gen-py-type_hints) generate(${MY_PROJECT_DIR}/test/Recursive.thrift py gen-py-default) generate(${MY_PROJECT_DIR}/test/Recursive.thrift py:slots gen-py-slots) @@ -38,3 +41,4 @@ generate(${MY_PROJECT_DIR}/test/Recursive.thrift py:no_utf8strings gen-py-no_utf generate(${MY_PROJECT_DIR}/test/Recursive.thrift py:dynamic gen-py-dynamic) generate(${MY_PROJECT_DIR}/test/Recursive.thrift py:dynamic,slots gen-py-dynamicslots) generate(${MY_PROJECT_DIR}/test/Recursive.thrift py:enum gen-py-enum) +generate(${MY_PROJECT_DIR}/test/Recursive.thrift py:type_hints,enum gen-py-type_hints) diff --git a/test/rb/Makefile.am b/test/rb/Makefile.am index 5dd75594618..9c5d557fd0d 100644 --- a/test/rb/Makefile.am +++ b/test/rb/Makefile.am @@ -33,5 +33,8 @@ endif clean-local: $(RM) -r gen-rb/ +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + dist-hook: $(RM) -r $(distdir)/gen-rb/ diff --git a/test/result.js b/test/result.js index 18b1a593d18..a6dd00a7a9f 100644 --- a/test/result.js +++ b/test/result.js @@ -18,47 +18,62 @@ */ -$.getJSON('results.json', function(results) { - $(document).ready(function() { - var transport = 3; - var socket = 4; - var success = 5; - var expected = 6; - var returnCode = 7; - var logFile = 8; - testTable = $('#test_results').DataTable({ - data: results['results'], - columnDefs: [ - { - targets: 3, - render: function(data, type, row) { - return row[transport] + '-' + row[socket]; - }, - }, - { - targets: 4, - render: function(data, type, row) { - return (row[success] ? 'success' : 'failure') - + '(' + (row[returnCode] == 128 ? 'timeout' : row[returnCode]) + ')' - + '(Server, ' - + 'Client)'; - }, - }, - { - targets: 5, - render: function(data, type, row) { - // 'yes' rather than 'expected' to ease search - return row[expected] ? 'yes' : 'unexpected'; - }, - } - ], - }); - $('#test_results_filter label input').focus().val('unexpected failure'); - $('#test_info').text( - "Test Date: " + results['date'] + "\n" + - "Revision: " + results['revision'] + "\n" + - "Platform: " + results['platform'] + "\n" + - "Test duration: " + results['duration']) + " seconds"; +$.getJSON("results.json", function (results) { + $(document).ready(function () { + var transport = 3; + var socket = 4; + var success = 5; + var expected = 6; + var returnCode = 7; + var logFile = 8; + testTable = $("#test_results").DataTable({ + data: results["results"], + columnDefs: [ + { + targets: 3, + render: function (data, type, row) { + return row[transport] + "-" + row[socket]; + }, + }, + { + targets: 4, + render: function (data, type, row) { + return ( + (row[success] ? "success" : "failure") + + "(" + + (row[returnCode] == 128 ? "timeout" : row[returnCode]) + + ")" + + '(Server, ' + + 'Client)' + ); + }, + }, + { + targets: 5, + render: function (data, type, row) { + // 'yes' rather than 'expected' to ease search + return row[expected] ? "yes" : "unexpected"; + }, + }, + ], }); + $("#test_results_filter label input").focus().val("unexpected failure"); + $("#test_info").text( + "Test Date: " + + results["date"] + + "\n" + + "Revision: " + + results["revision"] + + "\n" + + "Platform: " + + results["platform"] + + "\n" + + "Test duration: " + + results["duration"], + ) + " seconds"; + }); }); - diff --git a/test/rs/Makefile.am b/test/rs/Makefile.am index 78db5ee0c5c..6f5cf932052 100644 --- a/test/rs/Makefile.am +++ b/test/rs/Makefile.am @@ -34,6 +34,9 @@ clean-local: -$(RM) src/thrift_test.rs -$(RM) -r bin +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ Cargo.toml \ src/lib.rs \ diff --git a/test/rs/src/bin/test_client.rs b/test/rs/src/bin/test_client.rs index fd3a18550b9..801ccc4b504 100644 --- a/test/rs/src/bin/test_client.rs +++ b/test/rs/src/bin/test_client.rs @@ -252,10 +252,7 @@ fn make_thrift_calls( info!("testi64"); // try!(verify_expected_result(thrift_test_client.test_i64(-8651829879438294565), // -8651829879438294565)); - verify_expected_result( - thrift_test_client.test_i64(i64::min_value()), - i64::min_value(), - )?; + verify_expected_result(thrift_test_client.test_i64(i64::MIN), i64::MIN)?; info!("testDouble"); verify_expected_result( diff --git a/test/swift/CrossTests/Makefile.am b/test/swift/CrossTests/Makefile.am index b7d8fbb4902..5b332328af4 100644 --- a/test/swift/CrossTests/Makefile.am +++ b/test/swift/CrossTests/Makefile.am @@ -30,5 +30,8 @@ check: stubs clean-local: $(RM) -r Sources/Common/gen-swift/ +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + dist-hook: $(RM) -r $(distdir)/gen-swift/ diff --git a/test/swift/CrossTests/Sources/TestClient/main.swift b/test/swift/CrossTests/Sources/TestClient/main.swift index 6817981266c..d6274086942 100644 --- a/test/swift/CrossTests/Sources/TestClient/main.swift +++ b/test/swift/CrossTests/Sources/TestClient/main.swift @@ -40,7 +40,12 @@ class TestClient { } static func getTransport(parameters: TestClientParameters) throws -> TTransport { - let socketTransport = try TSocketTransport(hostname: parameters.host!, port: parameters.port!) + let socketTransport: TTransport = try { () throws -> TTransport in + if let domainSocket = parameters.domainSocket { + return try TSocketTransport(path: domainSocket) + } + return try TSocketTransport(hostname: parameters.host!, port: parameters.port!) + }() if parameters.transport == .framed { return TFramedTransport(transport: socketTransport) } diff --git a/test/swift/CrossTests/Sources/TestServer/main.swift b/test/swift/CrossTests/Sources/TestServer/main.swift index 15564d3e6ff..433bde7021e 100644 --- a/test/swift/CrossTests/Sources/TestServer/main.swift +++ b/test/swift/CrossTests/Sources/TestServer/main.swift @@ -34,19 +34,31 @@ class TestServer { let processor = ThriftTestProcessor(service: service) - switch (parameters.proto, parameters.transport) { - case (.binary, .buffered): + switch (parameters.proto, parameters.transport, parameters.domainSocket) { + case (.binary, .buffered, .none): let proto = TBinaryProtocol.self server = try TSocketServer(port: parameters.port!, inProtocol: proto, outProtocol: proto, processor: processor) - case (.binary, .framed): + case (.binary, .framed, .none): let proto = TBinaryProtocol.self server = try TFramedSocketServer(port: parameters.port!, inProtocol: proto, outProtocol: proto, processor: processor) - case (.compact, .buffered): + case (.compact, .buffered, .none): let proto = TCompactProtocol.self server = try TSocketServer(port: parameters.port!, inProtocol: proto, outProtocol: proto, processor: processor) - case (.compact, .framed): + case (.compact, .framed, .none): let proto = TCompactProtocol.self server = try TFramedSocketServer(port: parameters.port!, inProtocol: proto, outProtocol: proto, processor: processor) + case (.binary, .buffered, .some(let domainSocket)): + let proto = TBinaryProtocol.self + server = try TSocketServer(path: domainSocket, inProtocol: proto, outProtocol: proto, processor: processor) + case (.binary, .framed, .some(let domainSocket)): + let proto = TBinaryProtocol.self + server = try TFramedSocketServer(path: domainSocket, inProtocol: proto, outProtocol: proto, processor: processor) + case (.compact, .buffered, .some(let domainSocket)): + let proto = TCompactProtocol.self + server = try TSocketServer(path: domainSocket, inProtocol: proto, outProtocol: proto, processor: processor) + case (.compact, .framed, .some(let domainSocket)): + let proto = TCompactProtocol.self + server = try TFramedSocketServer(path: domainSocket, inProtocol: proto, outProtocol: proto, processor: processor) default: throw ParserError.unsupportedOption } diff --git a/test/swift/Makefile.am b/test/swift/Makefile.am index 20c2fe5c912..f81fba8786c 100644 --- a/test/swift/Makefile.am +++ b/test/swift/Makefile.am @@ -19,6 +19,9 @@ SUBDIRS = CrossTests +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + precross: $(MAKE) -C CrossTests precross diff --git a/test/test.py b/test/test.py index cd5c4d41d6e..a288c265ae1 100755 --- a/test/test.py +++ b/test/test.py @@ -27,7 +27,6 @@ # subprocess management that are needed for reliability. # -from __future__ import print_function from itertools import chain import json import logging diff --git a/test/tests.json b/test/tests.json index 2c7eaf99d8f..275f113666d 100644 --- a/test/tests.json +++ b/test/tests.json @@ -539,6 +539,31 @@ }, { "name": "php", + "server": { + "transports": [ + "buffered", + "framed" + ], + "sockets": [ + "ip" + ], + "protocols": [ + "binary", + "binary:accel", + "compact", + "json" + ], + "command": [ + "php", + "-dextension_dir=php_ext_dir", + "--php-ini=test_php.ini", + "--no-php-ini", + "-ddisplay_errors=stderr", + "-dlog_errors=0", + "-derror_reporting=E_ALL", + "TestServer.php" + ] + }, "client": { "timeout": 6, "transports": [ @@ -719,24 +744,31 @@ }, "client": { "timeout": 5, - "transports": [ - "buffered", - "framed", - "http" - ], - "sockets": [ - "ip" - ], - "protocols": [ - "binary", - "compact", - "json" - ], "command": [ "lua", "test_basic_client.lua" ] }, + "server": { + "delay": 5, + "command": [ + "lua", + "test_basic_server.lua" + ] + }, + "transports": [ + "buffered", + "framed", + "http" + ], + "sockets": [ + "ip" + ], + "protocols": [ + "binary", + "compact", + "json" + ], "workdir": "lua" }, { @@ -814,14 +846,14 @@ "workdir": "swift/CrossTests/.build/x86_64-unknown-linux-gnu/debug", "protocols": ["binary", "compact"], "transports": ["buffered", "framed"], - "sockets": ["ip"] + "sockets": ["ip", "domain"] }, "client": { "command": ["TestClient"], "workdir": "swift/CrossTests/.build/x86_64-unknown-linux-gnu/debug", "protocols": ["binary", "compact"], "transports": ["buffered", "framed"], - "sockets": ["ip"] + "sockets": ["ip", "domain"] } } ] diff --git a/tutorial/Makefile.am b/tutorial/Makefile.am index 24969d13b62..ab87c95eec3 100644 --- a/tutorial/Makefile.am +++ b/tutorial/Makefile.am @@ -101,6 +101,9 @@ clean-local: endif +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + # Any folders or files not listed above being added to SUBDIR need to be placed here in # EXTRA_DIST to be included in the release EXTRA_DIST = \ diff --git a/tutorial/c_glib/Makefile.am b/tutorial/c_glib/Makefile.am index f37649495f4..253f96261f0 100644 --- a/tutorial/c_glib/Makefile.am +++ b/tutorial/c_glib/Makefile.am @@ -79,6 +79,9 @@ tutorialserver: all tutorialclient: all ./tutorial_client +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ c_glib_server.c \ c_glib_client.c diff --git a/tutorial/cl/Makefile.am b/tutorial/cl/Makefile.am index 70c5e0730a5..aef5840f57a 100755 --- a/tutorial/cl/Makefile.am +++ b/tutorial/cl/Makefile.am @@ -57,6 +57,9 @@ clean-local: -$(RM) TutorialServer -$(RM) TutorialClient +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ tutorial-implementation.lisp \ shared-implementation.lisp \ diff --git a/tutorial/cpp/CppClient.cpp b/tutorial/cpp/CppClient.cpp index 520841143b4..02e7b17ce8c 100644 --- a/tutorial/cpp/CppClient.cpp +++ b/tutorial/cpp/CppClient.cpp @@ -43,9 +43,9 @@ int main() { transport->open(); client.ping(); - cout << "ping()" << endl; + cout << "ping()" << '\n'; - cout << "1 + 1 = " << client.add(1, 1) << endl; + cout << "1 + 1 = " << client.add(1, 1) << '\n'; Work work; work.op = Operation::DIVIDE; @@ -54,27 +54,27 @@ int main() { try { client.calculate(1, work); - cout << "Whoa? We can divide by zero!" << endl; + cout << "Whoa? We can divide by zero!" << '\n'; } catch (InvalidOperation& io) { - cout << "InvalidOperation: " << io.why << endl; - // or using generated operator<<: cout << io << endl; - // or by using std::exception native method what(): cout << io.what() << endl; + cout << "InvalidOperation: " << io.why << '\n'; + // or using generated operator<<: cout << io << '\n'; + // or by using std::exception native method what(): cout << io.what() << '\n'; } work.op = Operation::SUBTRACT; work.num1 = 15; work.num2 = 10; int32_t diff = client.calculate(1, work); - cout << "15 - 10 = " << diff << endl; + cout << "15 - 10 = " << diff << '\n'; // Note that C++ uses return by reference for complex types to avoid // costly copy construction SharedStruct ss; client.getStruct(ss, 1); - cout << "Received log: " << ss << endl; + cout << "Received log: " << ss << '\n'; transport->close(); } catch (TException& tx) { - cout << "ERROR: " << tx.what() << endl; + cout << "ERROR: " << tx.what() << '\n'; } } diff --git a/tutorial/cpp/CppServer.cpp b/tutorial/cpp/CppServer.cpp index 635afefda0d..4c66cb894d5 100644 --- a/tutorial/cpp/CppServer.cpp +++ b/tutorial/cpp/CppServer.cpp @@ -48,15 +48,15 @@ class CalculatorHandler : public CalculatorIf { public: CalculatorHandler() = default; - void ping() override { cout << "ping()" << endl; } + void ping() override { cout << "ping()" << '\n'; } int32_t add(const int32_t n1, const int32_t n2) override { - cout << "add(" << n1 << ", " << n2 << ")" << endl; + cout << "add(" << n1 << ", " << n2 << ")" << '\n'; return n1 + n2; } int32_t calculate(const int32_t logid, const Work& work) override { - cout << "calculate(" << logid << ", " << work << ")" << endl; + cout << "calculate(" << logid << ", " << work << ")" << '\n'; int32_t val; switch (work.op) { @@ -95,11 +95,11 @@ class CalculatorHandler : public CalculatorIf { } void getStruct(SharedStruct& ret, const int32_t logid) override { - cout << "getStruct(" << logid << ")" << endl; + cout << "getStruct(" << logid << ")" << '\n'; ret = log[logid]; } - void zip() override { cout << "zip()" << endl; } + void zip() override { cout << "zip()" << '\n'; } protected: map log; @@ -172,8 +172,8 @@ int main() { threadManager); */ - cout << "Starting the server..." << endl; + cout << "Starting the server..." << '\n'; server.serve(); - cout << "Done." << endl; + cout << "Done." << '\n'; return 0; } diff --git a/tutorial/cpp/Makefile.am b/tutorial/cpp/Makefile.am index 77fd6d579cd..d093df3efc0 100644 --- a/tutorial/cpp/Makefile.am +++ b/tutorial/cpp/Makefile.am @@ -78,6 +78,9 @@ tutorialclient: all style-local: $(CPPSTYLE_CMD) +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ CMakeLists.txt \ CppClient.cpp \ diff --git a/tutorial/d/Makefile.am b/tutorial/d/Makefile.am index 358294ce56d..3db3d15513f 100644 --- a/tutorial/d/Makefile.am +++ b/tutorial/d/Makefile.am @@ -47,6 +47,9 @@ clean: $(RM) -r gen-d/ find . -type f -name '*.o' | xargs rm -f +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + dist-hook: $(RM) -f $(distdir)/$(PROGS) $(RM) -r $(distdir)/gen-d/ diff --git a/tutorial/dart/Makefile.am b/tutorial/dart/Makefile.am index 860f292b762..e29e3c57caa 100644 --- a/tutorial/dart/Makefile.am +++ b/tutorial/dart/Makefile.am @@ -66,6 +66,9 @@ tutorialclient: pub-get-gen pub-get-client tutorialconsoleclient: pub-get-console-client ${DART} console_client/bin/main.dart +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ client/web/client.dart \ client/web/index.html \ diff --git a/tutorial/dart/client/pubspec.yaml b/tutorial/dart/client/pubspec.yaml index e8c6db8ab90..71b580c1630 100644 --- a/tutorial/dart/client/pubspec.yaml +++ b/tutorial/dart/client/pubspec.yaml @@ -16,7 +16,7 @@ # under the License. name: tutorial_client -version: 0.20.0 +version: 0.22.0 description: A Dart client implementation of the Apache Thrift tutorial author: Apache Thrift Developers homepage: http://thrift.apache.org diff --git a/tutorial/dart/console_client/pubspec.yaml b/tutorial/dart/console_client/pubspec.yaml index e5c0938b973..b7e2e5090e4 100644 --- a/tutorial/dart/console_client/pubspec.yaml +++ b/tutorial/dart/console_client/pubspec.yaml @@ -16,7 +16,7 @@ # under the License. name: tutorial_console_client -version: 0.20.0 +version: 0.22.0 description: > A Dart console client to implementation of the Apache Thrift tutorial author: Apache Thrift Developers diff --git a/tutorial/dart/server/pubspec.yaml b/tutorial/dart/server/pubspec.yaml index 5f7edb9bc25..f694118b389 100644 --- a/tutorial/dart/server/pubspec.yaml +++ b/tutorial/dart/server/pubspec.yaml @@ -16,7 +16,7 @@ # under the License. name: tutorial_server -version: 0.20.0 +version: 0.22.0 description: A Dart server to support the Apache Thrift tutorial author: Apache Thrift Developers homepage: http://thrift.apache.org diff --git a/tutorial/delphi/DelphiClient/DelphiClient.dproj b/tutorial/delphi/DelphiClient/DelphiClient.dproj index 34d9f03dc22..785de16ab31 100644 --- a/tutorial/delphi/DelphiClient/DelphiClient.dproj +++ b/tutorial/delphi/DelphiClient/DelphiClient.dproj @@ -124,13 +124,13 @@ popd]]> Thrift Tutorial - 0.20.0.0 + 0.22.0.0 DelphiClient Copyright © 2012 The Apache Software Foundation DelphiClient.exe Thrift - 0.20.0.0 + 0.22.0.0 diff --git a/tutorial/delphi/DelphiServer/DelphiServer.dproj b/tutorial/delphi/DelphiServer/DelphiServer.dproj index fa8cb92d84a..43c963afd05 100644 --- a/tutorial/delphi/DelphiServer/DelphiServer.dproj +++ b/tutorial/delphi/DelphiServer/DelphiServer.dproj @@ -121,13 +121,13 @@ popd]]> Thrift Tutorial - 0.20.0.0 + 0.22.0.0 DelphiServer Copyright © 2012 The Apache Software Foundation DelphiServer.exe Thrift - 0.20.0.0 + 0.22.0.0 diff --git a/tutorial/go/Makefile.am b/tutorial/go/Makefile.am index b2f70ce120c..16385b00c34 100644 --- a/tutorial/go/Makefile.am +++ b/tutorial/go/Makefile.am @@ -45,6 +45,9 @@ tutorialsecureclient: all clean-local: $(RM) -r gen-* go-tutorial calculator-remote +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ src/client.go \ src/handler.go \ diff --git a/tutorial/haxe/Makefile.am b/tutorial/haxe/Makefile.am index e6f27134680..d2c84f4c7af 100644 --- a/tutorial/haxe/Makefile.am +++ b/tutorial/haxe/Makefile.am @@ -79,6 +79,9 @@ tutorialclient_http: all clean-local: $(RM) -r gen-haxe bin +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ src \ cpp.hxml \ diff --git a/tutorial/java/Makefile.am b/tutorial/java/Makefile.am index 59e68bab2b1..afad8f557e9 100644 --- a/tutorial/java/Makefile.am +++ b/tutorial/java/Makefile.am @@ -39,6 +39,9 @@ tutorialserver: all tutorialclient: all $(ANT) $(ANT_FLAGS) tutorialclient +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ build.properties \ build.xml \ diff --git a/tutorial/js/Makefile.am b/tutorial/js/Makefile.am index 26a3c836ea7..ac0283f9c84 100644 --- a/tutorial/js/Makefile.am +++ b/tutorial/js/Makefile.am @@ -33,6 +33,9 @@ check-local: all tutorialserver: all $(ANT) $(ANT_FLAGS) tutorialserver +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ build.properties \ build.xml \ diff --git a/tutorial/netstd/Client/Client.csproj b/tutorial/netstd/Client/Client.csproj index 994d6be7be6..df3f6c929d5 100644 --- a/tutorial/netstd/Client/Client.csproj +++ b/tutorial/netstd/Client/Client.csproj @@ -19,12 +19,13 @@ --> - net8.0 + net9.0 latestMajor Client Client Exe - 0.20.0.0 + 0.22.0.0 + enable false false false @@ -32,7 +33,7 @@ - + diff --git a/tutorial/netstd/Client/Program.cs b/tutorial/netstd/Client/Program.cs index f1c5236e1af..93175fd46af 100644 --- a/tutorial/netstd/Client/Program.cs +++ b/tutorial/netstd/Client/Program.cs @@ -15,8 +15,8 @@ // specific language governing permissions and limitations // under the License. +using Microsoft.Extensions.Logging; using System; -using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; @@ -25,16 +25,12 @@ using System.Security.Cryptography.X509Certificates; using System.Threading; using System.Threading.Tasks; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.DependencyInjection; using Thrift; using Thrift.Protocol; using Thrift.Transport; using Thrift.Transport.Client; using tutorial; -using shared; -#pragma warning disable IDE0063 // using #pragma warning disable IDE0057 // substr namespace Client @@ -58,7 +54,7 @@ public static void ConfigureLogging(ILoggingBuilder logging) public class Program { private static readonly ILogger Logger = LoggingHelper.CreateLogger(); - private static readonly TConfiguration Configuration = null; // new TConfiguration() if needed + private static readonly TConfiguration Configuration = new(); private static void DisplayHelp() { @@ -97,11 +93,12 @@ will run client with specified arguments (tcp transport and binary protocol by d "); } - public static void Main(string[] args) + public static async Task Main(string[] args) { - args ??= Array.Empty(); + args ??= []; - if (args.Any(x => x.StartsWith("-help", StringComparison.OrdinalIgnoreCase))) + // -help is rather unusual but we leave it for compatibility + if (args.Any(x => x.Equals("-help") || x.Equals("--help") || x.Equals("-h") || x.Equals("-?"))) { DisplayHelp(); return; @@ -109,10 +106,8 @@ public static void Main(string[] args) Logger.LogInformation("Starting client..."); - using (var source = new CancellationTokenSource()) - { - RunAsync(args, source.Token).GetAwaiter().GetResult(); - } + using var source = new CancellationTokenSource(); + await RunAsync(args, source.Token); } @@ -150,7 +145,7 @@ private static bool GetMultiplex(string[] args) private static Protocol GetProtocol(string[] args) { - var protocol = args.FirstOrDefault(x => x.StartsWith("-pr"))?.Split(':')?[1]; + var protocol = args.FirstOrDefault(x => x.StartsWith("-pr"))?.Split(':').Skip(1).Take(1).FirstOrDefault(); if (string.IsNullOrEmpty(protocol)) return Protocol.Binary; @@ -163,7 +158,7 @@ private static Protocol GetProtocol(string[] args) private static Buffering GetBuffering(string[] args) { - var buffering = args.FirstOrDefault(x => x.StartsWith("-bf"))?.Split(":")?[1]; + var buffering = args.FirstOrDefault(x => x.StartsWith("-bf"))?.Split(':').Skip(1).Take(1).FirstOrDefault(); if (string.IsNullOrEmpty(buffering)) return Buffering.None; @@ -176,7 +171,7 @@ private static Buffering GetBuffering(string[] args) private static Transport GetTransport(string[] args) { - var transport = args.FirstOrDefault(x => x.StartsWith("-tr"))?.Split(':')?[1]; + var transport = args.FirstOrDefault(x => x.StartsWith("-tr"))?.Split(':').Skip(1).Take(1).FirstOrDefault(); if (string.IsNullOrEmpty(transport)) return Transport.Tcp; @@ -191,7 +186,7 @@ private static Transport GetTransport(string[] args) private static TTransport MakeTransport(string[] args) { // construct endpoint transport - TTransport transport = null; + TTransport? transport = null; Transport selectedTransport = GetTransport(args); { switch (selectedTransport) @@ -241,7 +236,7 @@ private static TTransport MakeTransport(string[] args) private static int GetNumberOfClients(string[] args) { - var numClients = args.FirstOrDefault(x => x.StartsWith("-mc"))?.Split(':')?[1]; + var numClients = args.FirstOrDefault(x => x.StartsWith("-mc"))?.Split(':').Skip(1).Take(1).FirstOrDefault(); Logger.LogInformation("Selected # of clients: {numClients}", numClients); @@ -254,35 +249,42 @@ private static int GetNumberOfClients(string[] args) 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"); + var dir = Directory.GetParent(Directory.GetCurrentDirectory()); + if (dir != null) + { + var certFile = GetCertPath(dir); + //return new X509Certificate2(certFile, "ThriftTest"); + return X509CertificateLoader.LoadPkcs12FromFile(certFile, "ThriftTest"); + } + else + { + Logger.LogError("Root path of {path} not found", Directory.GetCurrentDirectory()); + throw new Exception($"Root path of {Directory.GetCurrentDirectory()} not found"); + } } - private static string GetCertPath(DirectoryInfo di, int maxCount = 6) + private static string GetCertPath(DirectoryInfo? di, int maxCount = 6) { var topDir = di; - var certFile = - topDir.EnumerateFiles("ThriftTest.pfx", SearchOption.AllDirectories) - .FirstOrDefault(); + 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 GetCertPath(di?.Parent, --maxCount); } return certFile.FullName; } - private static X509Certificate LocalCertificateSelectionCallback(object sender, + private static X509Certificate2 LocalCertificateSelectionCallback(object sender, string targetHost, X509CertificateCollection localCertificates, - X509Certificate remoteCertificate, string[] acceptableIssuers) + X509Certificate? remoteCertificate, string[] acceptableIssuers) { return GetCertificate(); } - private static bool CertValidator(object sender, X509Certificate certificate, - X509Chain chain, SslPolicyErrors sslPolicyErrors) + private static bool CertValidator(object sender, X509Certificate? certificate, X509Chain? chain, SslPolicyErrors sslPolicyErrors) { return true; } diff --git a/tutorial/netstd/Interfaces/Interfaces.csproj b/tutorial/netstd/Interfaces/Interfaces.csproj index c3524575adc..9a243ea2ed8 100644 --- a/tutorial/netstd/Interfaces/Interfaces.csproj +++ b/tutorial/netstd/Interfaces/Interfaces.csproj @@ -19,10 +19,11 @@ --> - net6.0 + net9.0 Interfaces Interfaces - 0.20.0.0 + 0.22.0.0 + enable false false false @@ -34,15 +35,15 @@ - + - - - + + + diff --git a/tutorial/netstd/Makefile.am b/tutorial/netstd/Makefile.am index f295cc0729b..522601d2e3d 100644 --- a/tutorial/netstd/Makefile.am +++ b/tutorial/netstd/Makefile.am @@ -31,6 +31,9 @@ clean-local: $(RM) -r Interfaces/bin $(RM) -r Interfaces/obj +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ Client \ Interfaces \ diff --git a/tutorial/netstd/Server/Program.cs b/tutorial/netstd/Server/Program.cs index 01e7336c50f..a3b12fca95b 100644 --- a/tutorial/netstd/Server/Program.cs +++ b/tutorial/netstd/Server/Program.cs @@ -15,6 +15,12 @@ // specific language governing permissions and limitations // under the License. +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using shared; using System; using System.Collections.Generic; using System.IO; @@ -23,20 +29,13 @@ 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.Processor; using Thrift.Protocol; using Thrift.Server; using Thrift.Transport; using Thrift.Transport.Server; using tutorial; -using shared; -using Thrift.Processor; -using System.Diagnostics; #pragma warning disable IDE0057 // substr @@ -61,27 +60,25 @@ public static void ConfigureLogging(ILoggingBuilder logging) public class Program { private static readonly ILogger Logger = LoggingHelper.CreateLogger(); - private static readonly TConfiguration Configuration = null; // new TConfiguration() if needed + private static readonly TConfiguration Configuration = new(); - public static void Main(string[] args) + public static async Task Main(string[] args) { - args ??= Array.Empty(); + args ??= []; - if (args.Any(x => x.StartsWith("-help", StringComparison.OrdinalIgnoreCase))) + // -help is rather unusual but we leave it for compatibility + if (args.Any(x => x.Equals("-help") || x.Equals("--help") || x.Equals("-h") || x.Equals("-?"))) { DisplayHelp(); return; } - using (var source = new CancellationTokenSource()) - { - RunAsync(args, source.Token).GetAwaiter().GetResult(); - - Logger.LogInformation("Press any key to stop..."); + using var source = new CancellationTokenSource(); + await RunAsync(args, source.Token); - Console.ReadLine(); - source.Cancel(); - } + Logger.LogInformation("Press any key to stop..."); + Console.ReadLine(); + source.Cancel(); Logger.LogInformation("Server stopped"); } @@ -149,7 +146,7 @@ private static bool GetMultiplex(string[] args) private static Protocol GetProtocol(string[] args) { - var protocol = args.FirstOrDefault(x => x.StartsWith("-pr"))?.Split(':')?[1]; + var protocol = args.FirstOrDefault(x => x.StartsWith("-pr"))?.Split(':').Skip(1).Take(1).FirstOrDefault(); if (string.IsNullOrEmpty(protocol)) return Protocol.Binary; @@ -162,7 +159,7 @@ private static Protocol GetProtocol(string[] args) private static Buffering GetBuffering(string[] args) { - var buffering = args.FirstOrDefault(x => x.StartsWith("-bf"))?.Split(":")?[1]; + var buffering = args.FirstOrDefault(x => x.StartsWith("-bf"))?.Split(':').Skip(1).Take(1).FirstOrDefault(); if (string.IsNullOrEmpty(buffering)) return Buffering.None; @@ -175,7 +172,7 @@ private static Buffering GetBuffering(string[] args) private static Transport GetTransport(string[] args) { - var transport = args.FirstOrDefault(x => x.StartsWith("-tr"))?.Split(':')?[1]; + var transport = args.FirstOrDefault(x => x.StartsWith("-tr"))?.Split(':').Skip(1).Take(1).FirstOrDefault(); if (string.IsNullOrEmpty(transport)) return Transport.Tcp; @@ -196,7 +193,7 @@ private static async Task RunSelectedConfigurationAsync(Transport transport, Buf _ => throw new ArgumentException("unsupported value $transport", nameof(transport)), }; - TTransportFactory transportFactory = buffering switch + TTransportFactory? transportFactory = buffering switch { Buffering.Buffered => new TBufferedTransport.Factory(), Buffering.Framed => new TFramedTransport.Factory(), @@ -258,34 +255,32 @@ 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"); + //return new X509Certificate2(certFile, "ThriftTest"); + return X509CertificateLoader.LoadPkcs12FromFile(certFile, "ThriftTest"); } - private static string GetCertPath(DirectoryInfo di, int maxCount = 6) + private static string GetCertPath(DirectoryInfo? di, int maxCount = 6) { var topDir = di; - var certFile = - topDir.EnumerateFiles("ThriftTest.pfx", SearchOption.AllDirectories) - .FirstOrDefault(); + 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 GetCertPath(di?.Parent, --maxCount); } return certFile.FullName; } - private static X509Certificate LocalCertificateSelectionCallback(object sender, + private static X509Certificate2 LocalCertificateSelectionCallback(object sender, string targetHost, X509CertificateCollection localCertificates, - X509Certificate remoteCertificate, string[] acceptableIssuers) + X509Certificate? remoteCertificate, string[] acceptableIssuers) { return GetCertificate(); } - private static bool ClientCertValidator(object sender, X509Certificate certificate, - X509Chain chain, SslPolicyErrors sslPolicyErrors) + private static bool ClientCertValidator(object sender, X509Certificate? certificate, X509Chain? chain, SslPolicyErrors sslPolicyErrors) { return true; } @@ -369,7 +364,7 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerF public class CalculatorAsyncHandler : Calculator.IAsync { - private readonly Dictionary _log = new(); + private readonly Dictionary _log = []; public CalculatorAsyncHandler() { @@ -394,12 +389,12 @@ public async Task add(int num1, int num2, CancellationToken cancellationTok return await Task.FromResult(num1 + num2); } - public async Task calculate(int logid, Work w, CancellationToken cancellationToken) + public async Task calculate(int logid, Work? w, CancellationToken cancellationToken) { - Logger.LogInformation("Calculate({logid}, [{w.Op},{w.Num1},{w.Num2}])", logid, w.Op, w.Num1, w.Num2); + Logger.LogInformation("Calculate({logid}, [{w.Op},{w.Num1},{w.Num2}])", logid, w?.Op, w?.Num1, w?.Num2); int val; - switch (w.Op) + switch (w?.Op) { case Operation.ADD: val = w.Num1 + w.Num2; @@ -431,7 +426,7 @@ public async Task calculate(int logid, Work w, CancellationToken cancellati { var io = new InvalidOperation { - WhatOp = (int) w.Op, + WhatOp = ((int?)w?.Op) ?? -1, Why = "Unknown operation" }; diff --git a/tutorial/netstd/Server/Server.csproj b/tutorial/netstd/Server/Server.csproj index c72ec88ce34..b50b69c04e5 100644 --- a/tutorial/netstd/Server/Server.csproj +++ b/tutorial/netstd/Server/Server.csproj @@ -19,12 +19,13 @@ --> - net8.0 + net9.0 latestMajor Server Server Exe - 0.20.0.0 + 0.22.0.0 + enable false false false diff --git a/tutorial/nodejs/Makefile.am b/tutorial/nodejs/Makefile.am index 1516fec2cce..3798a31cb26 100644 --- a/tutorial/nodejs/Makefile.am +++ b/tutorial/nodejs/Makefile.am @@ -38,6 +38,9 @@ tutorialclient_promise: all clean-local: $(RM) -r gen-* +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ NodeServer.js \ NodeClient.js \ diff --git a/tutorial/nodejs/NodeClient.js b/tutorial/nodejs/NodeClient.js index b4886e82608..e4e92cc0f30 100644 --- a/tutorial/nodejs/NodeClient.js +++ b/tutorial/nodejs/NodeClient.js @@ -17,47 +17,44 @@ * under the License. */ -var thrift = require('thrift'); -var Calculator = require('./gen-nodejs/Calculator'); -var ttypes = require('./gen-nodejs/tutorial_types'); -const assert = require('assert'); +var thrift = require("thrift"); +var Calculator = require("./gen-nodejs/Calculator"); +var ttypes = require("./gen-nodejs/tutorial_types"); +const assert = require("assert"); var transport = thrift.TBufferedTransport; var protocol = thrift.TBinaryProtocol; var connection = thrift.createConnection("localhost", 9090, { - transport : transport, - protocol : protocol + transport: transport, + protocol: protocol, }); -connection.on('error', function(err) { +connection.on("error", function (err) { assert(false, err); }); // Create a Calculator client with the connection var client = thrift.createClient(Calculator, connection); - -client.ping(function(err, response) { - console.log('ping()'); +client.ping(function (err, response) { + console.log("ping()"); }); - -client.add(1,1, function(err, response) { +client.add(1, 1, function (err, response) { console.log("1+1=" + response); }); - work = new ttypes.Work(); work.op = ttypes.Operation.DIVIDE; work.num1 = 1; work.num2 = 0; -client.calculate(1, work, function(err, message) { +client.calculate(1, work, function (err, message) { if (err) { console.log("InvalidOperation " + err); } else { - console.log('Whoa? You know how to divide by zero?'); + console.log("Whoa? You know how to divide by zero?"); } }); @@ -65,11 +62,11 @@ work.op = ttypes.Operation.SUBTRACT; work.num1 = 15; work.num2 = 10; -client.calculate(1, work, function(err, message) { - console.log('15-10=' + message); +client.calculate(1, work, function (err, message) { + console.log("15-10=" + message); - client.getStruct(1, function(err, message){ - console.log('Check log: ' + message.value); + client.getStruct(1, function (err, message) { + console.log("Check log: " + message.value); //close the connection once we're done connection.end(); diff --git a/tutorial/nodejs/NodeClientPromise.js b/tutorial/nodejs/NodeClientPromise.js index e6ff2d7f42c..0ba5f4f005f 100644 --- a/tutorial/nodejs/NodeClientPromise.js +++ b/tutorial/nodejs/NodeClientPromise.js @@ -17,64 +17,62 @@ * under the License. */ -var thrift = require('thrift'); -var Calculator = require('./gen-nodejs/Calculator'); -var ttypes = require('./gen-nodejs/tutorial_types'); -const assert = require('assert'); +var thrift = require("thrift"); +var Calculator = require("./gen-nodejs/Calculator"); +var ttypes = require("./gen-nodejs/tutorial_types"); +const assert = require("assert"); var transport = thrift.TBufferedTransport; var protocol = thrift.TBinaryProtocol; var connection = thrift.createConnection("localhost", 9090, { - transport : transport, - protocol : protocol + transport: transport, + protocol: protocol, }); -connection.on('error', function(err) { +connection.on("error", function (err) { assert(false, err); }); // Create a Calculator client with the connection var client = thrift.createClient(Calculator, connection); +client.ping().then(function () { + console.log("ping()"); +}); -client.ping() - .then(function() { - console.log('ping()'); - }); - -client.add(1,1) - .then(function(response) { - console.log("1+1=" + response); - }); +client.add(1, 1).then(function (response) { + console.log("1+1=" + response); +}); work = new ttypes.Work(); work.op = ttypes.Operation.DIVIDE; work.num1 = 1; work.num2 = 0; -client.calculate(1, work) - .then(function(message) { - console.log('Whoa? You know how to divide by zero?'); +client + .calculate(1, work) + .then(function (message) { + console.log("Whoa? You know how to divide by zero?"); }) - .catch(function(err) { + .catch(function (err) { console.log("InvalidOperation " + err); }); - work.op = ttypes.Operation.SUBTRACT; work.num1 = 15; work.num2 = 10; -client.calculate(1, work) - .then(function(value) { - console.log('15-10=' + value); - return client.getStruct(1); +client + .calculate(1, work) + .then(function (value) { + console.log("15-10=" + value); + return client.getStruct(1); }) - .then(function(message) { - console.log('Check log: ' + message.value); + .then(function (message) { + console.log("Check log: " + message.value); }) - .finally(function() { - //close the connection once we're done - connection.end(); + .finally(function () { + //close the connection once we're done + connection.end(); }); diff --git a/tutorial/nodejs/NodeServer.js b/tutorial/nodejs/NodeServer.js index 2e198825c10..5181e5128d2 100644 --- a/tutorial/nodejs/NodeServer.js +++ b/tutorial/nodejs/NodeServer.js @@ -25,17 +25,17 @@ var SharedStruct = require("./gen-nodejs/shared_types").SharedStruct; var data = {}; var server = thrift.createServer(Calculator, { - ping: function(result) { + ping: function (result) { console.log("ping()"); result(null); }, - add: function(n1, n2, result) { + add: function (n1, n2, result) { console.log("add(", n1, ",", n2, ")"); result(null, n1 + n2); }, - calculate: function(logid, work, result) { + calculate: function (logid, work, result) { console.log("calculate(", logid, ",", work, ")"); var val = 0; @@ -49,7 +49,7 @@ var server = thrift.createServer(Calculator, { if (work.num2 === 0) { var x = new ttypes.InvalidOperation(); x.whatOp = work.op; - x.why = 'Cannot divide by 0'; + x.why = "Cannot divide by 0"; result(x); return; } @@ -57,28 +57,27 @@ var server = thrift.createServer(Calculator, { } else { var x = new ttypes.InvalidOperation(); x.whatOp = work.op; - x.why = 'Invalid operation'; + x.why = "Invalid operation"; result(x); return; } var entry = new SharedStruct(); entry.key = logid; - entry.value = ""+val; + entry.value = "" + val; data[logid] = entry; result(null, val); }, - getStruct: function(key, result) { + getStruct: function (key, result) { console.log("getStruct(", key, ")"); result(null, data[key]); }, - zip: function() { + zip: function () { console.log("zip()"); - } - + }, }); server.listen(9090); diff --git a/tutorial/nodejs/NodeServerPromise.js b/tutorial/nodejs/NodeServerPromise.js index bff287b1823..ddd18f4990c 100644 --- a/tutorial/nodejs/NodeServerPromise.js +++ b/tutorial/nodejs/NodeServerPromise.js @@ -25,16 +25,16 @@ var SharedStruct = require("./gen-nodejs/shared_types").SharedStruct; var data = {}; var server = thrift.createServer(Calculator, { - ping: function() { + ping: function () { console.log("ping()"); }, - add: function(n1, n2) { + add: function (n1, n2) { console.log("add(", n1, ",", n2, ")"); return n1 + n2; }, - calculate: function(logid, work) { + calculate: function (logid, work) { console.log("calculate(", logid, ",", work, ")"); var val = 0; @@ -48,33 +48,32 @@ var server = thrift.createServer(Calculator, { if (work.num2 === 0) { var x = new ttypes.InvalidOperation(); x.whatOp = work.op; - x.why = 'Cannot divide by 0'; - throw x; + x.why = "Cannot divide by 0"; + throw x; } val = work.num1 / work.num2; } else { var x = new ttypes.InvalidOperation(); x.whatOp = work.op; - x.why = 'Invalid operation'; + x.why = "Invalid operation"; throw x; } var entry = new SharedStruct(); entry.key = logid; - entry.value = ""+val; + entry.value = "" + val; data[logid] = entry; return val; }, - getStruct: function(key) { + getStruct: function (key) { console.log("getStruct(", key, ")"); return data[key]; }, - zip: function() { + zip: function () { console.log("zip()"); - } - + }, }); server.listen(9090); diff --git a/tutorial/ocaml/_oasis b/tutorial/ocaml/_oasis index 6072e4b969f..12ec7f9edbf 100644 --- a/tutorial/ocaml/_oasis +++ b/tutorial/ocaml/_oasis @@ -1,5 +1,5 @@ Name: tutorial -Version: 0.20.0 +Version: 0.22.0 OASISFormat: 0.3 Synopsis: OCaml Tutorial example Authors: Apache Thrift Developers diff --git a/tutorial/perl/Makefile.am b/tutorial/perl/Makefile.am index fe77213bbf3..d28165afcba 100644 --- a/tutorial/perl/Makefile.am +++ b/tutorial/perl/Makefile.am @@ -31,6 +31,9 @@ tutorialclient: all clean-local: $(RM) -r gen-* +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ PerlServer.pl \ PerlClient.pl diff --git a/tutorial/php/Makefile.am b/tutorial/php/Makefile.am index 3d30ad999e6..1d11e05cba8 100644 --- a/tutorial/php/Makefile.am +++ b/tutorial/php/Makefile.am @@ -31,6 +31,9 @@ tutorialclient: all clean-local: $(RM) -r gen-* +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ PhpServer.php \ PhpClient.php \ diff --git a/tutorial/py.tornado/Makefile.am b/tutorial/py.tornado/Makefile.am index 4b73c1e72db..d8996a70826 100644 --- a/tutorial/py.tornado/Makefile.am +++ b/tutorial/py.tornado/Makefile.am @@ -31,6 +31,9 @@ tutorialclient: all clean-local: $(RM) -r gen-* +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ PythonServer.py \ PythonClient.py diff --git a/tutorial/py.twisted/Makefile.am b/tutorial/py.twisted/Makefile.am index 50cd3429d9a..f617d7cff56 100644 --- a/tutorial/py.twisted/Makefile.am +++ b/tutorial/py.twisted/Makefile.am @@ -31,6 +31,9 @@ tutorialclient: all clean-local: $(RM) -r gen-* +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ PythonClient.py \ PythonServer.py \ diff --git a/tutorial/py/Makefile.am b/tutorial/py/Makefile.am index 7db816d3bcf..da59815fe7c 100644 --- a/tutorial/py/Makefile.am +++ b/tutorial/py/Makefile.am @@ -31,6 +31,9 @@ tutorialclient: all clean-local: $(RM) -r gen-* +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ setup.cfg \ PythonServer.py \ diff --git a/tutorial/rb/Makefile.am b/tutorial/rb/Makefile.am index 885cd92318e..3dd4e313328 100644 --- a/tutorial/rb/Makefile.am +++ b/tutorial/rb/Makefile.am @@ -31,6 +31,9 @@ tutorialclient: all clean-local: $(RM) -r gen-* +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ RubyServer.rb \ RubyClient.rb diff --git a/tutorial/rs/Makefile.am b/tutorial/rs/Makefile.am index 13f670794f5..bbdf7cb085a 100644 --- a/tutorial/rs/Makefile.am +++ b/tutorial/rs/Makefile.am @@ -45,6 +45,9 @@ clean-local: -$(RM) src/tutorial.rs -$(RM) -r bin +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + EXTRA_DIST = \ Cargo.toml \ src/lib.rs \ diff --git a/tutorial/rs/src/bin/tutorial_client.rs b/tutorial/rs/src/bin/tutorial_client.rs index 4bf2ec098a0..b79ae83e204 100644 --- a/tutorial/rs/src/bin/tutorial_client.rs +++ b/tutorial/rs/src/bin/tutorial_client.rs @@ -107,7 +107,7 @@ fn new_client( // open the underlying TCP stream println!("connecting to tutorial server on {}:{}", host, port); - c.open(&format!("{}:{}", host, port))?; + c.open(format!("{}:{}", host, port))?; // clone the TCP channel into two halves, one which // we'll use for reading, the other for writing diff --git a/tutorial/swift/Makefile.am b/tutorial/swift/Makefile.am index e8b8b2284cb..bb1e61244c6 100644 --- a/tutorial/swift/Makefile.am +++ b/tutorial/swift/Makefile.am @@ -23,6 +23,9 @@ gen_swift: $(THRIFT) --gen swift -r -o Sources/Common $(top_srcdir)/tutorial/tutorial.thrift +distdir: + $(MAKE) $(AM_MAKEFLAGS) distdir-am + tutorial: gen_swift swift run TutorialRunner